Take-home Exercise 2: Applied Spatial Interaction Models: A case study of Singapore public bus commuter flows

Published

December 7, 2023

Modified

December 14, 2023

1 Overview

Urban mobility, characterized by the daily commute of urban dwellers from homes to workplaces, presents complex challenges for transport operators and urban managers. Traditional approaches to understanding these mobility patterns, such as commuter surveys, are often hindered by high costs, time-consuming processes, and the rapid obsolescence of collected data. However, the digitalisation of city-wide urban infrastructures, including public buses, mass rapid transits, and other utilities, alongside the advent of pervasive computing technologies like GPS and SMART cards, offers a new paradigm in tracking and analyzing urban movement.

Objectives

This assignment is driven by two primary motivations. First, despite the growing availability of open data for public use, there is a noticeable gap in applied research demonstrating how these diverse data sources can be effectively integrated and analyzed to inform policy-making decisions. Second, there is a need to showcase how GDSA can be utilized in practical decision-making scenarios.

The core task of this assignment is to conduct a case study that exhibits the potential value of GDSA. By leveraging publicly available data from multiple sources, the goal is to build spatial interaction models that unravel the factors influencing urban mobility patterns, particularly focusing on public bus transit. This exercise aims to bridge the gap between the abundance of geospatially-referenced data and its practical application, thereby enhancing the return on investment in data collection and management, and ultimately supporting informed policy-making in urban mobility.

The specific tasks of this take-home exercise are as follows:

Geospatial Data Science

  • Derive an analytical hexagon data of 375m (this distance is the perpendicular distance between the centre of the hexagon and its edges) to represent the traffic analysis zone (TAZ).

  • With reference to the time intervals provided in the table below, construct an O-D matrix of commuter flows for a time interval of your choice by integrating Passenger Volume by Origin Destination Bus Stops and Bus Stop Location from LTA DataMall. The O-D matrix must be aggregated at the analytics hexagon level

    Peak hour period Bus tap on time
    Weekday morning peak 6am to 9am
    Weekday afternoon peak 5pm to 8pm
    Weekend/holiday morning peak 11am to 2pm
    Weekend/holiday evening peak 4pm to 7pm
  • Display the O-D flows of the passenger trips by using appropriate geovisualisation methods (not more than 5 maps).

  • Describe the spatial patterns revealed by the geovisualisation (not more than 100 words per visual).

  • Assemble at least three propulsive and three attractiveness variables by using aspatial and geospatial from publicly available sources.

  • Compute a distance matrix by using the analytical hexagon data derived earlier.

Spatial Interaction Modelling

  • Calibrate spatial interactive models to determine factors affecting urban commuting flows at the selected time interval.

  • Present the modelling results by using appropriate geovisualisation and graphical visualisation methods. (Not more than 5 visuals)

  • With reference to the Spatial Interaction Model output tables, maps and data visualisation prepared, describe the modelling results. (not more than 100 words per visual).

2 Loading Packages

The following packages will be used for this exercise:

Package Description
tmap For thematic mapping
sf & sp For importing, integrating, processing, and transforming geospatial data
tidyverse For non-spatial data wrangling
knitr For dynamic report generation
scales For scaling graphs
pacman::p_load(tmap, sf, sp, 
               tidyverse, DT, performance, 
               reshape2, ggpubr, stplanr,
               knitr, scales, corrplot, gtsummary)

3 Data Preparation

For the purpose of this assignment, the following data will be used:

Type Name As of Date Format Source
1 Aspatial Passenger Volume by Origin Destination Bus Stops Oct 2023 .csv LTA DataMall
2 Aspatial School Directory and Information (General information of schools) Mar 2022 .csv Data.gov.sg
3 Aspatial HDB Property Information (Geocoded) Sep 2021 .csv Courtesy of Prof T. S. Kam
4 Geospatial Bus Stop Location Jul 2023 .shp LTA DataMall
5 Geospatial Train Station Feb 2023 .shp LTA DataMall
6 Geospatial Train Station Exit Point Aug 2023 .shp LTA DataMall
7 Geospatial Master Plan 2019 Subzone Boundary 2019 .shp Courtesy of Prof T.S. Kam
8 Geospatial Business (incl. industrial parks), entertn, F&B, FinServ, Leisure&Recreation and Retails (Geospatial data sets of the locations of business establishments, entertainments, food and beverage outlets, financial centres, leisure and recreation centres, retail and services stores/outlets compiled for urban mobility study) .shp Courtesy of Prof T.S. Kam

3.1 O-D Data

Passenger Volume by Origin Destination Bus Stops dataset for October 2023, downloaded from LTA DataMall by using read_csv() or readr package.

odbus <- read_csv("data/aspatial/origin_destination_bus_202310.csv")

glimpse() of the dplyr package allows us to see all columns and their data type in the data frame.

glimpse(odbus)
Rows: 5,694,297
Columns: 7
$ YEAR_MONTH          <chr> "2023-10", "2023-10", "2023-10", "2023-10", "2023-…
$ DAY_TYPE            <chr> "WEEKENDS/HOLIDAY", "WEEKDAY", "WEEKENDS/HOLIDAY",…
$ TIME_PER_HOUR       <dbl> 16, 16, 14, 14, 17, 17, 17, 7, 14, 14, 10, 20, 20,…
$ PT_TYPE             <chr> "BUS", "BUS", "BUS", "BUS", "BUS", "BUS", "BUS", "…
$ ORIGIN_PT_CODE      <chr> "04168", "04168", "80119", "80119", "44069", "2028…
$ DESTINATION_PT_CODE <chr> "10051", "10051", "90079", "90079", "17229", "2014…
$ TOTAL_TRIPS         <dbl> 3, 5, 3, 5, 4, 1, 24, 2, 1, 7, 3, 2, 5, 1, 1, 1, 1…

Observations:

  • There are 7 variables in the odbus tibble data, they are:
    • YEAR_MONTH: Month in which data is collected
    • DAY_TYPE: Weekdays or weekends/holidays
    • TIME_PER_HOUR: Hour which the passenger trip is based on, in intervals from 0 to 23 hours
    • PT_TYPE: Type of public transport, i.e. bus
    • ORIGIN_PT_CODE: Origin bus stop ID
    • DESTINATION_PT_CODE: Destination bus stop ID
  • TOTAL_TRIPS: Number of trips We also note that values in ORIGIN_PT_CODE and DESTINATON_PT_CODE are in numeric data type. These should be in factor data type for further processing and georeferencing.

as.factor() can be used to convert the variables ORIGIN_PT_CODE and DESTINATON_PT_CODE from numeric to categorical data type. We use glimpse() again to check the results.

odbus$ORIGIN_PT_CODE <- as.factor(odbus$ORIGIN_PT_CODE)
odbus$DESTINATION_PT_CODE <- as.factor(odbus$DESTINATION_PT_CODE)

glimpse(odbus)
Rows: 5,694,297
Columns: 7
$ YEAR_MONTH          <chr> "2023-10", "2023-10", "2023-10", "2023-10", "2023-…
$ DAY_TYPE            <chr> "WEEKENDS/HOLIDAY", "WEEKDAY", "WEEKENDS/HOLIDAY",…
$ TIME_PER_HOUR       <dbl> 16, 16, 14, 14, 17, 17, 17, 7, 14, 14, 10, 20, 20,…
$ PT_TYPE             <chr> "BUS", "BUS", "BUS", "BUS", "BUS", "BUS", "BUS", "…
$ ORIGIN_PT_CODE      <fct> 04168, 04168, 80119, 80119, 44069, 20281, 20281, 1…
$ DESTINATION_PT_CODE <fct> 10051, 10051, 90079, 90079, 17229, 20141, 20141, 1…
$ TOTAL_TRIPS         <dbl> 3, 5, 3, 5, 4, 1, 24, 2, 1, 7, 3, 2, 5, 1, 1, 1, 1…

Note that both of them are in factor data type now.

In our study, we would like to analyse the 1 of the peak hour periods identified. We will be analysing the Weekday Morning peak periods thereafter. Therefore, we can employ a combination of the following functions to obtain the relevant data:

Summary of the functions used as follow:

  • filter(): Retains rows that satisfies our condition (i.e. Weekday Morning peak period)

  • select() of dplyr package: Retains the desired variables for further analysis.

  • group_by() and summarise(): Aggregates the total trips at each combination of origin bus stop, destination bus stop, and peak period.

WDMpeak <- odbus %>%
  filter(DAY_TYPE=="WEEKDAY" & (TIME_PER_HOUR >= 6 & TIME_PER_HOUR <= 9)) %>% 
  dplyr::select(5:7)  %>% 
  group_by(ORIGIN_PT_CODE, DESTINATION_PT_CODE) %>% 
  summarise(TRIPS=sum(TOTAL_TRIPS))

Let’s check the output using the glimpse() function of dplyr.

glimpse(WDMpeak)
Rows: 242,208
Columns: 3
Groups: ORIGIN_PT_CODE [5,029]
$ ORIGIN_PT_CODE      <fct> 01012, 01012, 01012, 01012, 01012, 01012, 01012, 0…
$ DESTINATION_PT_CODE <fct> 01112, 01113, 01121, 01211, 01311, 07371, 60011, 6…
$ TRIPS               <dbl> 290, 118, 77, 118, 165, 14, 30, 16, 35, 26, 2, 8, …

3.2 Geospatial Data

For the purpose of this exercise, three geospatial data will be used. They are:

  • MPSZ-2019: This data provides the sub-zone boundary of URA Master Plan 2019.
  • BusStop: This data provides the location of bus stop as at Jul 2023.
  • Analytical hexagon: Hexagonal grids of 375m (this distance is the perpendicular distance between the centre of the hexagon and its edges) to represent the traffic analysis zone.

In this section, we import the shapefiles into RStudio using st_read() function of sf package. st_transform() function of sf package is used to transform the projection to coordinate reference system (CRS) 3414, which is the EPSG code for the SVY21 projection used in Singapore.

mpsz <- st_read(dsn="data/geospatial",                   
                layer="MPSZ-2019")%>%   
  st_transform(crs = 3414)
Reading layer `MPSZ-2019' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 332 features and 6 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 103.6057 ymin: 1.158699 xmax: 104.0885 ymax: 1.470775
Geodetic CRS:  WGS 84

In the code chunk below, tm_shape() of tmap package is used to define the input data (i.e mpsz) and tm_polygons() is used to draw the planning subzone polygons.

busstop <- st_read(dsn = "data/geospatial",
                   layer = "BusStop") %>% 
  st_transform(crs = 3414)
Reading layer `BusStop' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 5161 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 3970.122 ymin: 26482.1 xmax: 48284.56 ymax: 52983.82
Projected CRS: SVY21

Busstop represents sf point objects for 5161 bus stop in Singapore.

To visualise the points of the bus stops, we can use tm_shape() of tmap package with each bus stop point displayed as dots. tmap_mode allows us to view static maps with plot and interactive maps with view.

Before proceeding, let’s check if there are any duplicated bus stops in the dataset.

bs_dupes <- busstop %>%
  group_by(BUS_STOP_N) %>%
  filter(n() > 1) %>%
  ungroup() %>%
  arrange(BUS_STOP_N)

knitr::kable(bs_dupes)
BUS_STOP_N BUS_ROOF_N LOC_DESC geometry
11009 B04 Ghim Moh Ter POINT (23101.34 32594.17)
11009 B04-TMNL GHIM MOH TER POINT (23100.58 32604.36)
22501 B02 Blk 662A POINT (13489.09 35536.4)
22501 B02 BLK 662A POINT (13488.02 35537.88)
43709 B06 BLK 644 POINT (18963.42 36762.8)
43709 B06 BLK 644 POINT (18952.02 36751.83)
47201 UNK NA POINT (22616.75 47793.68)
47201 NIL W’LANDS NTH STN POINT (22632.92 47934)
51071 B21 MACRITCHIE RESERVOIR POINT (28311.27 36036.92)
51071 B21 MACRITCHIE RESERVOIR POINT (28282.54 36033.93)
52059 B03 OPP BLK 65 POINT (30770.3 34460.06)
52059 B09 BLK 219 POINT (30565.45 36133.15)
53041 B05 Upp Thomson Road POINT (28105.8 37246.76)
53041 B07 Upp Thomson Road POINT (27956.34 37379.29)
58031 UNK OPP CANBERRA DR POINT (27089.69 47570.9)
58031 UNK OPP CANBERRA DR POINT (27111.07 47517.77)
62251 B03 Bef Blk 471B POINT (35500.54 39943.41)
62251 B03 BEF BLK 471B POINT (35500.36 39943.34)
67421 B01 CHENG LIM STN EXIT B POINT (34548.54 42052.15)
67421 NIL CHENG LIM STN EXIT B POINT (34741.77 42004.21)
68091 B01 AFT BAKER ST POINT (32164.11 42695.98)
68091 B08 AFT BAKER ST POINT (32038.84 43298.68)
68099 B02 BEF BAKER ST POINT (32154.9 42742.82)
68099 B07 BEF BAKER ST POINT (32004.05 43320.34)
77329 B01 BEF PASIR RIS ST 53 POINT (40765.35 39452.18)
77329 B03 Pasir Ris Central POINT (40728.15 39438.15)
82221 B01 BLK 3A POINT (35323.6 33257.05)
82221 B01 Blk 3A POINT (35308.74 33335.17)
96319 NA Yusen Logistics POINT (42187.23 34995.78)
96319 NIL YUSEN LOGISTICS POINT (42187.23 34995.78)
97079 B14 OPP ST. JOHN’S CRES POINT (44144.57 38980.25)
97079 B14 OPP ST. JOHN’S CRES POINT (44055.75 38908.5)

The results displayed 16 pairs of duplicated ‘BUS_STOP_N’, with each pair showing a different geometry point for the same bus stop number. This could potentially suggest that these are temporary bus stops. In that case, it would be prudent to retain only one of them, as conventionally, only one bus stop is used at a time.

busstop <- busstop %>%
  distinct(BUS_STOP_N, 
           .keep_all = TRUE)

Notice that the number of bus stops has dropped from 5161 to 5145.

Note from the choropleth map that there are 5 bus stops located outside Singapore, they are bus stops 46239, 46609, 47701, 46211, and 46219. The code chunk below uses filter() to exclude the 5 bus stops outside Singapore.

busstop <- busstop %>%   
  filter(!BUS_STOP_N %in% c(46239, 46609, 47701, 46211, 46219))

Notice that the number of bus stops has dropped from 5145 to 5140.

A hexagonal grid is used to represent the traffic analysis zones, which helps to model travel demand through capturing the spatial aspects of trip origins and destinations.

Step 1: Create Hexagonal Grids

We first create a hexagonal grid layer of 375m (refers to the perpendicular distance between the centre of the hexagon and its edges) with st_make_grid, st_sf to convert the grid into an sf object with the codes below, and row_number() to assign an ID to each hexagon.

st_make_grid function is used to create a grid over a spatial object. It takes 4 arguments, they are:

  • x: sf object; the input spatial data

  • cellsize: for hexagonal cells the distance between opposite edges in the unit of the crs the spatial data is using. In this case, we take cellsize to be 375m * 2 = 750m

  • what: character; one of: "polygons", "corners", or "centers"
  • square: indicates whether you are a square grid (TRUE) or hexagon grid (FALSE)
area_hexagon_grid = st_make_grid(busstop, 
                                 cellsize= 750, 
                                 what = "polygons", 
                                 square = FALSE,
                                 crs = 3414) %>% 
  st_sf() %>% 
  mutate(grid_id = row_number())

Step 2: Remove grids with no bus stops

We count the number of bus stops in each grid and retain only the grids with bus stops using the code chunks below.

st_intersects is used to identify the bus stops falling inside each hexagon, while lengths returns the number of bus stops inside each hexagon.

# Create a column containing the count of bus stops in each grid
area_hexagon_grid$busstops = lengths(st_intersects(area_hexagon_grid, busstop))

# Retain hexagons with bus stops
area_hexagon_grid = filter(area_hexagon_grid, busstops > 0)

Notice that 831 hexagons have been created.

Step 3: Check & Visualise

sum(area_hexagon_grid$busstops, na.rm = TRUE)
[1] 5140

Note that there are 5140 bus stops, which tallies to the 5140 from the Busstop shape file after deducting for the 5 bus stops outside Singapore boundary and the 16 duplicates, suggesting that the hexagons have managed to capture all expected bus stops.

In the bar chart below, it is evident that the distribution of bus stops per hexagon is right-skewed. While one hexagon contains as many as 19 bus stops, the majority have fewer than 10 bus stops.

Lastly, using tm_shape from tmap package, we can quickly visualise the results of the hexagon grids we have created.

3.3 Geospatial Data Wrangling

3.3.1 Combining Busstop and Hexagons

Code chunk below populates the grid ID (i.e. grid_id) of area_hexagon_grid sf data frame into busstop sf data frame using the following functions:

  • st_intersection() is used to perform point and polygon overly and the output will be in point sf object.

  • select() of dplyr package is then use to retain preferred variables from the data frames.

  • st_stop_geometry() removes the geometry data to manipulate it like a regular dataframe using tidyr and dplyr functions

bs_wgrids <- st_intersection(busstop, area_hexagon_grid) %>% 
  dplyr::select(BUS_STOP_N,BUS_ROOF_N,LOC_DESC, grid_id) %>% 
  st_drop_geometry

Before we proceed, let’s perform a duplicates check on bs_wgrids.

duplicate <- bs_wgrids %>%
  group_by_all() %>%
  filter(n()>1) %>%
  ungroup()

duplicate
# A tibble: 0 × 4
# ℹ 4 variables: BUS_STOP_N <chr>, BUS_ROOF_N <chr>, LOC_DESC <chr>,
#   grid_id <int>

Results showed that there are no duplicated records.

3.3.2 Populate Passenger Volume data with Grid IDs

Next, we are going to append the Grid IDs based on origin bus stops from bs_wgrids data frame onto WDMpeak data frame.

od_data <- left_join(WDMpeak , bs_wgrids,
            by = c("ORIGIN_PT_CODE" = "BUS_STOP_N")) %>% 
  rename(ORIGIN_BS = ORIGIN_PT_CODE,
         ORIGIN_GRID = grid_id,
         ORIGIN_DESC = LOC_DESC,
         DESTIN_BS = DESTINATION_PT_CODE)

Next, we will update od_data data frame with the Grid IDs of destination bus stops.

od_data <- left_join(od_data , bs_wgrids,
            by = c("DESTIN_BS" = "BUS_STOP_N")) %>% 
           rename(DESTIN_GRID = grid_id,
                  DESTIN_DESC = LOC_DESC)

glimpse(od_data)
Rows: 242,208
Columns: 9
Groups: ORIGIN_BS [5,029]
$ ORIGIN_BS    <chr> "01012", "01012", "01012", "01012", "01012", "01012", "01…
$ DESTIN_BS    <chr> "01112", "01113", "01121", "01211", "01311", "07371", "60…
$ TRIPS        <dbl> 290, 118, 77, 118, 165, 14, 30, 16, 35, 26, 2, 8, 1, 2, 2…
$ BUS_ROOF_N.x <chr> "B03", "B03", "B03", "B03", "B03", "B03", "B03", "B03", "…
$ ORIGIN_DESC  <chr> "HOTEL GRAND PACIFIC", "HOTEL GRAND PACIFIC", "HOTEL GRAN…
$ ORIGIN_GRID  <int> 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 1334, 133…
$ BUS_ROOF_N.y <chr> "B07", "B09", "B11", "B13", "B01", "B01", "B01", "B03", "…
$ DESTIN_DESC  <chr> "OPP BUGIS STN EXIT C", "BUGIS STN EXIT B", "STAMFORD PR …
$ DESTIN_GRID  <int> 1354, 1354, 1392, 1392, 1411, 1411, 1393, 1431, 1450, 143…

The code chunk below allows us to check for duplicates to prevent double counting. The results indicate that there are no duplicates found.

duplicate2 <- od_data %>%
  group_by_all() %>%
  filter(n()>1) %>%
  ungroup()

duplicate2
# A tibble: 0 × 9
# ℹ 9 variables: ORIGIN_BS <chr>, DESTIN_BS <chr>, TRIPS <dbl>,
#   BUS_ROOF_N.x <chr>, ORIGIN_DESC <chr>, ORIGIN_GRID <int>,
#   BUS_ROOF_N.y <chr>, DESTIN_DESC <chr>, DESTIN_GRID <int>

Next, the code chunk below removes rows with missing data using drop_na() and aggregates the total passenger trips at each origin-destination grid level with group_by() and summarise(). ORIGIN_nBS and DESTIN_nBS counts the number of bus stops, while ORIGIN_DESC and DESTIN_DESC provides the descriptions of each of the bus stops at origin and destination grids respectively.

od_data <- od_data %>%
  drop_na() %>%
  group_by(ORIGIN_GRID, DESTIN_GRID) %>%
  summarise(MORNING_PEAK = sum(TRIPS),
            ORIGIN_nBS = n_distinct(ORIGIN_BS),
            ORIGIN_DESC = str_c(ORIGIN_DESC, collapse = ", "),
            DESTIN_nBS = n_distinct(DESTIN_BS),            
            DESTIN_DESC = str_c(DESTIN_DESC, collapse = ", ")) %>% 
  ungroup()

Our resulting OD Matrix organises the commuter flows for weekday morning peak period in a column-wise format, with origin_grid representing the from and destin_grid representing the to. There are a total of 65,559 unique origin grid to destination grid combinations.

4 Visualising Spatial Interaction

Origin-destination flow maps are a popular option to visualise connections between different spatial locations. It reflects the relationships/flows between locations and are created by monitoring movements. In our analysis, we can use OD flows to identify the patterns of bus ridership during weekday mornings.

4.1 Removing Intra-Zonal Flows

Intrazonal travels are considered localised and short duration trips within a transportation analysis zone (i.e. within a hexagon). For our analysis, we will be removing them.

od_data1 <- od_data[od_data$ORIGIN_GRID!=od_data$DESTIN_GRID,]

There are 623 intra-zonal travels noted from the decrease in observations from 65,559 to 64,936.

4.2 OD Flow Distribution

   0%   10%   20%   30%   40%   50%   60%   70%   80%   90%  100% 
    1     2     5    11    21    37    67   124   252   658 77433 

From the summary statistics above, the minimum number of passenger trips for each combination of origin and destination bus stop is 1. The maximum observed is 77,433 passengers, occurring during the weekday morning peak period. Furthermore, the 90th percentile is 174 passengers. This data suggests a highly right-skewed distribution.

4.2 Creating Flow Lines

Desire lines visually represent the connections between originating and destination hexagons using straight lines. The od2line() function of stplanr package is utilized to create these lines. The width of each desire line is proportional to number of passenger trips, i.e. thicker lines would represent higher ridership.

# Creating centroids representing desire line start and end points
flowLine <- od2line(flow = od_data1, 
                    zones = area_hexagon_grid,
                    zone_code = "grid_id")

Since there are 65,559 different flow lines resulting from combinations of origin to destination hexagons, an excess of intersecting lines can cause visual clutter and obscure analysis. Considering that the 90th percentile is 658, we will focus on inter-zonal flows with the top 10% of ridership.

The map reveals that Yew Tee, Woodlands, and Yishun dominate bus ridership during weekday mornings, with notably wider desire lines. Key routes include travel within Yew Tee, between Woodlands Checkpoint and Woodlands MRT Station, as well as within Woodlands and Yishun. Interestingly, though broad, these desire lines are relatively short, often indicating bus travel to neighboring hexagons. This suggests a higher demand for feeder bus services in these areas during weekday mornings. Areas such as Boon Lay, Bedok, Choa Chu Kang, Clementi, Tampines, Pasir Ris, and Serangoon also display high concentrations and variations of desire lines with neighboring hexagons, indicating higher ridership within these areas.

Furthermore, longer desire lines between the North and East (i.e., Woodlands and Changi) suggest passengers’ willingness to travel longer distances to their destinations.

While OD flows provide valuable insights by quickly visualizing travel patterns, it is beneficial to complement them with other forms of analysis, such as spatial interaction models, for a more comprehensive understanding of the factors affecting urban commuting flow.

5 Computing Distance Matrix

A distance matrix is a two-dimensional array containing the distances between different locations. In our analysis, we can use a distance matrix to calculate the distance passengers are willing to travel by bus to get to their destinations.

5.1 Converting from sf data.table to SpatialPolygonsDataFrame

Firstly, as.Spatial() will be used to convert area_hexagon_grid from sf tibble data frame to SpatialPolygonsDataFrame of sp object as shown in the code chunk below.

hexgrid_sp <- as(area_hexagon_grid, "Spatial")
hexgrid_sp
class       : SpatialPolygonsDataFrame 
features    : 831 
extent      : 3595.122, 48595.12, 26049.09, 50297.8  (xmin, xmax, ymin, ymax)
crs         : +proj=tmerc +lat_0=1.36666666666667 +lon_0=103.833333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs 
variables   : 2
names       : grid_id, busstops 
min values  :      21,        1 
max values  :    2267,       19 

5.2 Computing Distance Matrix

Next, spDists() of sp package will be used to compute the Euclidean distance between the centroids of the planning subzones. spDists returns a full matrix of distances in the metric of the points if longlat=FALSE, or in kilometers if longlat=TRUE. With 831 hexagons, the return results will produce a 831 by 831 matrix of distance between each hexagon.

dist <- spDists(hexgrid_sp, 
                longlat = FALSE)

head(dist, n=c(8, 8))
         [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
[1,]    0.000  750.000 3269.174 1500.000 2704.163 3968.627 1299.038 2250.000
[2,]  750.000    0.000 2598.076  750.000 1984.313 3269.174  750.000 1500.000
[3,] 3269.174 2598.076    0.000 1984.313  750.000  750.000 2704.163 1500.000
[4,] 1500.000  750.000 1984.313    0.000 1299.038 2598.076  750.000  750.000
[5,] 2704.163 1984.313  750.000 1299.038    0.000 1299.038 1984.313  750.000
[6,] 3968.627 3269.174  750.000 2598.076 1299.038    0.000 3269.174 1984.313
[7,] 1299.038  750.000 2704.163  750.000 1984.313 3269.174    0.000 1299.038
[8,] 2250.000 1500.000 1500.000  750.000  750.000 1984.313 1299.038    0.000

The resulting output is a matrix object class, but column headers and row headers are not labeled with the grid IDs. We rename the headers for clarity.

grid_id <- area_hexagon_grid$grid_id

colnames(dist) <- paste0(grid_id)
rownames(dist) <- paste0(grid_id)

head(dist, n=c(8, 8))
         21       40       42       60       61       62       78       79
21    0.000  750.000 3269.174 1500.000 2704.163 3968.627 1299.038 2250.000
40  750.000    0.000 2598.076  750.000 1984.313 3269.174  750.000 1500.000
42 3269.174 2598.076    0.000 1984.313  750.000  750.000 2704.163 1500.000
60 1500.000  750.000 1984.313    0.000 1299.038 2598.076  750.000  750.000
61 2704.163 1984.313  750.000 1299.038    0.000 1299.038 1984.313  750.000
62 3968.627 3269.174  750.000 2598.076 1299.038    0.000 3269.174 1984.313
78 1299.038  750.000 2704.163  750.000 1984.313 3269.174    0.000 1299.038
79 2250.000 1500.000 1500.000  750.000  750.000 1984.313 1299.038    0.000

Notice that the column and row names have been updated to the grid IDs.

5.3 Pivoting Distance Value by Grid ID

Next, we will pivot the distance matrix into a long table by using the row and column grid IDs using (melt())[https://www.rdocumentation.org/packages/reshape2/versions/1.4.4/topics/melt] of the reshape2 package, as shown in the code chunk below.

distPair <- melt(dist) %>%
  rename(dist = value,
         orig = Var1,
         dest = Var2)

head(distPair, 10)
   orig dest     dist
1    21   21    0.000
2    40   21  750.000
3    42   21 3269.174
4    60   21 1500.000
5    61   21 2704.163
6    62   21 3968.627
7    78   21 1299.038
8    79   21 2250.000
9    80   21 3436.932
10   81   21 4683.748

Notice that the within zone distance is 0.

5.4 Updating Intra-Zonal Distances

In this section, we are going to append a constant value to replace the intra-zonal distance of 0.

First, we will select and find out the minimum value of the distance by using summary().

distPair %>%
  filter(dist > 0) %>%
  summary()
      orig           dest           dist      
 Min.   :  21   Min.   :  21   Min.   :  750  
 1st Qu.: 789   1st Qu.: 789   1st Qu.: 8250  
 Median :1200   Median :1200   Median :13269  
 Mean   :1150   Mean   :1150   Mean   :14135  
 3rd Qu.:1529   3rd Qu.:1529   3rd Qu.:18929  
 Max.   :2267   Max.   :2267   Max.   :44680  

Next, an arbitrary constant distance value of 100m is added into intra-zones distance

distPair$dist <- ifelse(distPair$dist == 0,
                        100, 
                        distPair$dist)

The code chunk below will be used to check the result data.frame.

# Check the result data.frame.
summary(distPair)
      orig           dest           dist      
 Min.   :  21   Min.   :  21   Min.   :  100  
 1st Qu.: 789   1st Qu.: 789   1st Qu.: 8250  
 Median :1200   Median :1200   Median :13269  
 Mean   :1150   Mean   :1150   Mean   :14119  
 3rd Qu.:1529   3rd Qu.:1529   3rd Qu.:18929  
 Max.   :2267   Max.   :2267   Max.   :44680  

Lastly, the code chunk below is used to save the dataframe for future use.

write_rds(distPair, "data/rds/distPair.rds") 

5.5 Combining passenger volume data with distance value

Let’s convert the origin and destination grid data in od_data and distPair into factor data type before we combine passenger volume data from od_data and distance from distPair using left_join().

od_data$ORIGIN_GRID  <- as.factor(od_data$ORIGIN_GRID)
od_data$DESTIN_GRID  <- as.factor(od_data$DESTIN_GRID)

distPair$orig  <- as.factor(distPair$orig)
distPair$dest  <- as.factor(distPair$dest)

flow_data <- od_data %>%
  left_join (distPair,
             by = c("ORIGIN_GRID" = "orig",
                    "DESTIN_GRID" = "dest"))

glimpse(flow_data)
Rows: 65,559
Columns: 8
$ ORIGIN_GRID  <fct> 21, 21, 21, 21, 21, 21, 40, 40, 40, 40, 40, 40, 40, 40, 4…
$ DESTIN_GRID  <fct> 61, 79, 116, 140, 159, 160, 21, 61, 78, 80, 116, 136, 140…
$ MORNING_PEAK <dbl> 1, 1, 4, 3, 93, 1, 1, 2, 1, 2, 3, 1, 2, 40, 1, 1, 3, 2, 2…
$ ORIGIN_nBS   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ ORIGIN_DESC  <chr> "AFT TUAS STH BLVD", "AFT TUAS STH BLVD", "AFT TUAS STH B…
$ DESTIN_nBS   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, …
$ DESTIN_DESC  <chr> "THE INDEX", "ABBOTT", "AFT TUAS STH ST 7", "BEF TUAS AVE…
$ dist         <dbl> 2704.163, 2250.000, 1984.313, 6873.864, 7611.669, 8842.37…

5.6 Distance Distribution

       0%       10%       20%       30%       40%       50%       60%       70% 
  100.000  1500.000  2598.076  3436.932  4500.000  5408.327  6538.348  7937.254 
      80%       90%      100% 
 9807.523 12346.558 24784.067 

From the summary statistics above, the minimum number of passenger trips for each combination of origin and destination bus stop is 100m, which is the arbitrary intrazonal travel distance we have set. The maximum observed is 24,784m.

5.6 Visualise Flow Lines

Since the 90th percentile of the distance traveled is 12,346.558m, we will filter the data for distances greater than 12,347m to analyse the top 10% of the longest distances traveled.

The plot below reveals that longer travel distances predominantly occur between North and North-East regions (i.e., Woodlands/Yishun and Punggol), North and East (Woodlands and Tampines), West and South (Choa Chu Kang/Bukit Panjang and the Town area), and North and South (Yishun and the Town area). These patterns may reflect commuting trends or the distribution of residential and commercial areas, suggesting that significant portions of the population undertake considerable daily commutes. Understanding these long-distance travel patterns is crucial for planning efficient public transport services, particularly in enhancing connectivity between these widely separated areas.

Let’s now move on to explore the potential factors that could attract or propel passengers to travel by bus from one location to another. This exploration will include examining various urban elements such as the proximity to key amenities like schools, shopping centers, and employment hubs. Understanding these elements can provide valuable insights into improving public transportation systems and urban planning strategies.

6. Preparing Origin and Destination Attributes

The following information is used to derive propulsive/attractiveness variables:

  1. Business, FinServ, Leisure&Recreation and Retails are geospatial data sets of the locations of business establishments, entertainments, food and beverage outlets, financial centres, leisure and recreation centres, retail and services stores/outlets.

  2. Schools: This data set contains directory and general information of schools in Singapore, obtained from data.gov.

  3. HDB: This data set is the geocoded version of HDB Property Information data from data.gov. The data set is prepared using September 2021 data.

trainstationexits contains the MRT station names and exits along with their respective point geometries in CRS SVY21.

Train stations exits reflect the intermodal connections with bus stops. In the context of attractiveness, these stations can be seen as destinations that attract passengers, including those who might transit to/from these stations by bus. The data can also indicate the propulsiveness aspect – how these stations act as origins for passengers who leave the MRT stations and then proceed to their final destinations via other modes of transportation like buses.

Step 1: Import shapefile

st_read() function of the sf package enables us to import the file into RStudio.

trainstationexits <- st_read(dsn = "data/geospatial",
                   layer = "Train_Station_Exit_layer") %>% 
  st_transform(crs = 3414)
Reading layer `Train_Station_Exit_layer' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 565 features and 2 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 6134.086 ymin: 27499.7 xmax: 45356.36 ymax: 47865.92
Projected CRS: SVY21

Notice there are 565 train station exits in total.

A quick check for duplicates revealed that there are cases where same station names and exit codes have different geometries. In the absence of further information, it is prudent to retain all these details, as they might represent cases where lifts and escalators at the exits are located at different points.

trainstationexits %>%
  group_by(stn_name, exit_code) %>%
  filter(n() > 1) %>%
  ungroup() %>%
  arrange(stn_name, exit_code) %>% 
  kable()
stn_name exit_code geometry
BEDOK NORTH MRT STATION Exit B POINT (37542.44 35150.99)
BEDOK NORTH MRT STATION Exit B POINT (37550.39 35173.81)
BUKIT PANJANG MRT STATION Exit A POINT (20054.56 40109.33)
BUKIT PANJANG MRT STATION Exit A POINT (19795.81 40301.42)
BUKIT PANJANG MRT STATION Exit A POINT (20066.96 40082.6)
CHOA CHU KANG MRT STATION Exit A POINT (18121.99 40819.65)
CHOA CHU KANG MRT STATION Exit A POINT (18122.31 40816.19)
CHOA CHU KANG MRT STATION Exit C POINT (18117.61 40853.37)
CHOA CHU KANG MRT STATION Exit C POINT (18112.29 40852.68)
CHOA CHU KANG MRT STATION Exit D POINT (18084.87 40849.96)
CHOA CHU KANG MRT STATION Exit D POINT (18072.23 40812.88)
EXPO MRT STATION Exit A POINT (42314.55 35278.98)
EXPO MRT STATION Exit A POINT (42302.73 35296.8)
HARBOURFRONT MRT STATION Exit A POINT (26569.87 27614.83)
HARBOURFRONT MRT STATION Exit A POINT (26797.06 27512.2)
UPPER CHANGI MRT STATION Exit A POINT (42246.13 36002.08)
UPPER CHANGI MRT STATION Exit A POINT (42205.19 36018.15)

Step 2: Point-in-Polygon Count Process

Next, we will count the number of train station exits located inside each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_TRAINSTATIONEXIT`<- lengths(
  st_intersects(
    area_hexagon_grid, trainstationexits))

sum(area_hexagon_grid$COUNT_TRAINSTATIONEXIT)
[1] 560

The 5 train station exits not accounted for could be in areas outside hexagons where there are no bus stop.

Summary statistics indicate that a maximum of 13 train station exits are located within a single hexagon, while at least 75% of the hexagons do not contain any exits.

summary(area_hexagon_grid$COUNT_TRAINSTATIONEXIT)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.0000  0.0000  0.6739  0.0000 13.0000 

Let’s visualise where these are located:

Show the code
tmap_mode("plot")
tm_shape(mpsz) +
  tm_polygons(alpha = 0) +
  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(trainstationexits) +
  tm_dots()

business contains the details of various businesses from SMEs to bigger groups like Pan Pacific, as well as the respective point geometries in CRS SVY21.

Businesses serve as significant attractors in a city. They draw people to these locations, primarily for work purposes. The presence and density of businesses in an area can significantly influence the flow of commuters, making it a measure of attractiveness.

Step 1: Import shapefile

Show the code
business <- st_read(dsn = "data/geospatial",
                      layer = "Business") %>%
          st_transform(crs = 3414)
Reading layer `Business' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 6550 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 3669.148 ymin: 25408.41 xmax: 47034.83 ymax: 50148.54
Projected CRS: SVY21 / Singapore TM

Note that there are 6550 business in our dataset in total.

Our duplicate check showed KEPPEL DISTRIPARK is included twice in the dataset. We remove this to prevent double-counting.

business %>%
  group_by_all() %>%
  filter(n() > 1) %>%
  ungroup() %>%
  arrange(POI_NAME) %>% 
  kable()
POI_NAME POI_ST_NUM POI_ST_NAM geometry
KEPPEL DISTRIPARK 511 KG BAHRU RD POINT (27455.94 28233.69)
KEPPEL DISTRIPARK 511 KG BAHRU RD POINT (27455.94 28233.69)
business <- unique(business)

Note that the number of records for business is has decreased from 6550 to 6549.

Step 2: Point-in-Polygon Count Process

Next, we will count the number of business in each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_BIZ`<- lengths(
  st_intersects(
    area_hexagon_grid, business))

Summary statistics below show that less than half of the hexagons contain no businesses, while in contrast, a single hexagon houses as many as 97 businesses.

summary(area_hexagon_grid$COUNT_BIZ)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.000   0.000   1.000   7.298   7.000  97.000 

Let’s visualise where these are located are using the code chunk below:

Show the code
tmap_mode("plot")
tm_shape(mpsz) +
  tm_polygons(alpha = 0) +
  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(trainstationexits) +
  tm_dots()

finserv contains the details of various financial centres, as well as the respective point geometries in CRS SVY21.

Financial service locations often represent significant employment centers, especially in urban and commercial areas. Many people travel to these locations for work, making them important attractors during morning peak hours. In addition, financial services typically adhere to standard office hours, which aligns well with the morning peak period of bus ridership, as a large proportion of employees would be traveling to work during this time.

Step 1: Import shapefile

Show the code
finserv <- st_read(dsn = "data/geospatial",
                      layer = "FinServ") %>%
          st_transform(crs = 3414)
Reading layer `FinServ' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 3320 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 4881.527 ymin: 25171.88 xmax: 46526.16 ymax: 49338.02
Projected CRS: SVY21 / Singapore TM

Note that there are 3320 locations of financial services in our dataset in total.

Similarly, we remove duplicates to prevent double-counting. This reduces the number of financial services locations from 3320 to 3058.

finserv <- unique(finserv)

Step 2: Point-in-Polygon Count Process

Next, we will count the number of financial services in each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_FS`<- lengths(
  st_intersects(
    area_hexagon_grid, finserv))

The summary statistics reveal that up to 130 financial services locations can be found within a single hexagon, with less than half of the hexagons are devoid of any such locations.

summary(area_hexagon_grid$COUNT_FS)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.000   0.000   1.000   3.626   4.000 130.000 

Let’s visualise where these are located are using the code chunk below:

Show the code
tmap_mode("plot")
tm_shape(mpsz) +
  tm_polygons(alpha = 0) +
  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(finserv) +
  tm_dots()

recs includes information on various leisure and recreation centers, such as playgrounds, parks, and fitness centers. It also contains their respective point geometries in the CRS SVY21.

Recreational facilities could be popular for early morning workouts and might be an attractor for the morning crowd.

Step 1: Import shapefile

Show the code
recs <- st_read(dsn = "data/geospatial",
                      layer = "Liesure&Recreation") %>%
          st_transform(crs = 3414)
Reading layer `Liesure&Recreation' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 1217 features and 30 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 6010.495 ymin: 25134.28 xmax: 48439.77 ymax: 50078.88
Projected CRS: SVY21 / Singapore TM

Note that there are 1217 locations of leisure and recreational centres in our dataset in total.

The results from the duplicate check show that no duplicates were found

finserv %>%
  group_by_all() %>%
  filter(n() > 1) %>%
  ungroup() %>%
  arrange(POI_NAME) %>% 
  kable()
POI_NAME POI_ST_NUM POI_ST_NAM geometry

Step 2: Point-in-Polygon Count Process

Next, we will count the number of facilities in each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_RECS`<- lengths(
  st_intersects(
    area_hexagon_grid, recs))

The summary statistics indicate that, on average, a single leisure and recreational facility is found within each hexagon, although the highest number recorded in a hexagon is 41.

summary(area_hexagon_grid$COUNT_RECS)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.000   0.000   0.000   1.312   1.000  41.000 

Let’s visualise where these are located are using the code chunk below:

Show the code
tmap_mode("plot")
tm_shape(mpsz) +
  tm_polygons(alpha = 0) +
  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(recs) +
  tm_dots()

retail includes information on various retail and services stores/outlets, along with their respective point geometries in the CRS SVY21.

Retail locations can be significant attractors in the morning, particularly as employment destinations for people who work in these retail and service outlets. Some retail services, like coffee shops, breakfast spots, and convenience stores, might attract early morning customers, including commuters heading to work.

Step 1: Import shapefile

Show the code
retail <- st_read(dsn = "data/geospatial",
                  layer = "Retails") %>%
          st_transform(crs = 3414)
Reading layer `Retails' from data source 
  `C:\kytjy\ISSS624\Take-Home_Ex\Take-Home_Ex2\data\geospatial' 
  using driver `ESRI Shapefile'
Simple feature collection with 37635 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 4737.982 ymin: 25171.88 xmax: 48265.04 ymax: 50135.28
Projected CRS: SVY21 / Singapore TM

Note that there are 37635 retail locations in our dataset in total.

Similarly, we remove duplicates to prevent double-counting. This reduces the number of retail services locations from 37,635 to 37,460.

retail <- unique(retail)

Step 2: Point-in-Polygon Count Process

Next, we will count the number of retail centres in each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_RETAIL`<- lengths(
  st_intersects(
    area_hexagon_grid, retail))

The summary statistics reveal that, on average, 44 retail and service centers can be located within a single hexagon, with the maximum number reaching 1669.

summary(area_hexagon_grid$COUNT_RETAIL)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00    1.00    8.00   43.99   36.50 1669.00 

Let’s visualise where these are located are using the code chunk below:

Show the code
tmap_mode("plot")
tm_shape(mpsz) +
  tm_polygons(alpha = 0) +
  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(retail) +
  tm_dots()

The schools data is a geocoded version of the School Directory and Information from data.gov. This information was prepared with OneMap API using the March 2022 data. For detailed steps, please visit Prof Kam’s ISSS624.

Schools significantly impact local transit patterns, especially during morning and afternoon peak hours. Regular travel routines of students, teachers, and staff create predictable demand, with a high volume of commuters contributing substantially to local transit ridership, making it a critical attractor. This effect is particularly pronounced on bus routes serving school areas, where the demand for public transit is heightened around school start and end times.

Step 1: Import csv file

schools <- read_csv("data/aspatial/schools.csv") %>%
  rename(latitude = "results.LATITUDE",
         longitude = "results.LONGITUDE")%>%
  select(postal_code, school_name, latitude, longitude)

A quick check for duplicates showed that there are 4 duplicates found, we remove these to prevent double-counting.

schools %>%
  group_by_all() %>%
  filter(n() > 1) %>%
  ungroup() %>%
  arrange(school_name) %>% 
  kable()
postal_code school_name latitude longitude
599986 METHODIST GIRLS’ SCHOOL (PRIMARY) 1.332662 103.7834
599986 METHODIST GIRLS’ SCHOOL (PRIMARY) 1.332662 103.7834
599986 METHODIST GIRLS’ SCHOOL (SECONDARY) 1.332662 103.7834
599986 METHODIST GIRLS’ SCHOOL (SECONDARY) 1.332662 103.7834
309437 SINGAPORE CHINESE GIRLS’ PRIMARY SCHOOL 1.320634 103.8282
309437 SINGAPORE CHINESE GIRLS’ PRIMARY SCHOOL 1.320634 103.8282
309437 SINGAPORE CHINESE GIRLS’ SCHOOL 1.320634 103.8282
309437 SINGAPORE CHINESE GIRLS’ SCHOOL 1.320634 103.8282

Note that the number of schools has dropped from 350 to 346.

schools <- unique(schools)

Step 2: Convert into sf tibble data.frame

To transform longitude and latitude into point geometries for further analysis, we can use st_as_sf to convert coordinates into spatial geometry objects and st_transform to help in assigning to Singapore’s coordinate system with EPSG 3414.

schools_sf <- st_as_sf(schools, 
                       coords = c("longitude", "latitude"),
                       crs=4326) %>%
  st_transform(crs = 3414)

Step 3: Point-in-Polygon Count Process

Next, we will count the number of schools in each hexagon and include this as a variable in area_hexagon_grid table.

area_hexagon_grid$`COUNT_SCHOOLS`<- lengths(
  st_intersects(
    area_hexagon_grid, schools_sf))

The summary statistics reveal that more than half of the hexagons do not contain any schools, with the maximum number of schools in a single hexagon being 4. We see from the map plotted above that two of such hexagons are located at Choa Chu Kang and Marine Parade.

summary(area_hexagon_grid$COUNT_SCHOOLS)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.0000  0.0000  0.4103  1.0000  4.0000 

Let’s visualise where these are located:

Show the code
tmap_mode("view")
#tm_shape(mpsz) +
#  tm_polygons(alpha = 0) +
#  tm_borders(alpha = 0.5)+
tm_shape(area_hexagon_grid) +
  tm_fill(alpha=0.7, 
          palette="RdBu") +
  tm_borders(alpha = 0.5)+
tm_shape(schools_sf) +
  tm_dots()

The hdb dataset is a geocoded version of the HDB Property Information from data.gov, provided courtesy of Prof. Kam. It encompasses details such as addresses and characteristics of Housing Development Board (HDB) blocks, complete with longitude and latitude coordinates. The number of total_dwelling_units in these blocks serves as an indicative measure of the propulsive factor during weekday morning peak periods.

Significantly, HDB blocks house the majority of Singapore’s population, making this dataset particularly valuable for urban and transportation planning. The number of dwelling units in a housing area is a robust indicator of population density. Typically, higher density translates to a greater potential for public transport usage, especially buses, during peak commuting times. Consequently, areas with a high concentration of dwelling units are likely to see substantial demand for public transportation services during peak hours as residents commute to work, school, or other daily activities.

Step 1: Import csv file

hdb <- read_csv("data/aspatial/hdb.csv")

str(hdb)
spc_tbl_ [12,442 × 37] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ ...1                 : num [1:12442] 0 1 2 3 4 5 6 7 8 9 ...
 $ blk_no               : chr [1:12442] "1" "1" "1" "1" ...
 $ street               : chr [1:12442] "BEACH RD" "BEDOK STH AVE 1" "CANTONMENT RD" "CHAI CHEE RD" ...
 $ max_floor_lvl        : num [1:12442] 16 14 2 15 4 25 12 14 12 2 ...
 $ year_completed       : num [1:12442] 1970 1975 2010 1982 1975 ...
 $ residential          : chr [1:12442] "Y" "Y" "N" "Y" ...
 $ commercial           : chr [1:12442] "Y" "N" "Y" "N" ...
 $ market_hawker        : chr [1:12442] "N" "N" "N" "N" ...
 $ miscellaneous        : chr [1:12442] "N" "Y" "N" "N" ...
 $ multistorey_carpark  : chr [1:12442] "N" "N" "N" "N" ...
 $ precinct_pavilion    : chr [1:12442] "N" "N" "N" "N" ...
 $ bldg_contract_town   : chr [1:12442] "KWN" "BD" "CT" "BD" ...
 $ total_dwelling_units : num [1:12442] 142 206 0 102 55 96 125 247 95 0 ...
 $ 1room_sold           : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ 2room_sold           : num [1:12442] 1 0 0 0 0 0 0 0 0 0 ...
 $ 3room_sold           : num [1:12442] 138 204 0 0 54 0 118 0 62 0 ...
 $ 4room_sold           : num [1:12442] 1 0 0 10 0 0 0 0 0 0 ...
 $ 5room_sold           : num [1:12442] 2 2 0 92 1 96 7 0 33 0 ...
 $ exec_sold            : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ multigen_sold        : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ studio_apartment_sold: num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ 1room_rental         : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ 2room_rental         : num [1:12442] 0 0 0 0 0 0 0 247 0 0 ...
 $ 3room_rental         : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ other_room_rental    : num [1:12442] 0 0 0 0 0 0 0 0 0 0 ...
 $ lat                  : num [1:12442] 1.3 1.32 1.28 1.33 1.39 ...
 $ lng                  : num [1:12442] 104 104 104 104 104 ...
 $ building             : chr [1:12442] "RAFFLES HOTEL" "NIL" "PINNACLE @ DUXTON" "PING YI GARDENS" ...
 $ addr                 : chr [1:12442] "1 BEACH ROAD RAFFLES HOTEL SINGAPORE 189673" "1 BEDOK SOUTH AVENUE 1 SINGAPORE 460001" "1 CANTONMENT ROAD PINNACLE @ DUXTON SINGAPORE 080001" "1 CHAI CHEE ROAD PING YI GARDENS SINGAPORE 461001" ...
 $ postal               : chr [1:12442] "189673" "460001" "080001" "461001" ...
 $ SUBZONE_NO           : num [1:12442] 2 6 3 3 1 9 10 5 3 5 ...
 $ SUBZONE_N            : chr [1:12442] "CITY HALL" "BEDOK SOUTH" "CHINATOWN" "KEMBANGAN" ...
 $ SUBZONE_C            : chr [1:12442] "DTSZ02" "BDSZ06" "OTSZ03" "BDSZ03" ...
 $ PLN_AREA_N           : chr [1:12442] "DOWNTOWN CORE" "BEDOK" "OUTRAM" "BEDOK" ...
 $ PLN_AREA_C           : chr [1:12442] "DT" "BD" "OT" "BD" ...
 $ REGION_N             : chr [1:12442] "CENTRAL REGION" "EAST REGION" "CENTRAL REGION" "EAST REGION" ...
 $ REGION_C             : chr [1:12442] "CR" "ER" "CR" "ER" ...
 - attr(*, "spec")=
  .. cols(
  ..   ...1 = col_double(),
  ..   blk_no = col_character(),
  ..   street = col_character(),
  ..   max_floor_lvl = col_double(),
  ..   year_completed = col_double(),
  ..   residential = col_character(),
  ..   commercial = col_character(),
  ..   market_hawker = col_character(),
  ..   miscellaneous = col_character(),
  ..   multistorey_carpark = col_character(),
  ..   precinct_pavilion = col_character(),
  ..   bldg_contract_town = col_character(),
  ..   total_dwelling_units = col_double(),
  ..   `1room_sold` = col_double(),
  ..   `2room_sold` = col_double(),
  ..   `3room_sold` = col_double(),
  ..   `4room_sold` = col_double(),
  ..   `5room_sold` = col_double(),
  ..   exec_sold = col_double(),
  ..   multigen_sold = col_double(),
  ..   studio_apartment_sold = col_double(),
  ..   `1room_rental` = col_double(),
  ..   `2room_rental` = col_double(),
  ..   `3room_rental` = col_double(),
  ..   other_room_rental = col_double(),
  ..   lat = col_double(),
  ..   lng = col_double(),
  ..   building = col_character(),
  ..   addr = col_character(),
  ..   postal = col_character(),
  ..   SUBZONE_NO = col_double(),
  ..   SUBZONE_N = col_character(),
  ..   SUBZONE_C = col_character(),
  ..   PLN_AREA_N = col_character(),
  ..   PLN_AREA_C = col_character(),
  ..   REGION_N = col_character(),
  ..   REGION_C = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

The below code chunk retains relevant columns for further analysis:

hdb <- hdb %>%  
  select(c("blk_no", "street", "total_dwelling_units", "lat", "lng"))

Step 2: Convert into sf tibble data.frame

To transform longitude and latitude into point geometries for further analysis, we can use st_as_sf to convert coordinates into spatial geometry objects and st_transform to help in assigning to Singapore’s coordinate system with EPSG 3414.

hdb_sf <- st_as_sf(hdb, 
                       coords = c("lng", "lat"),
                       crs=4326) %>%
  st_transform(crs = 3414)

Step 3: Counting the Total Dwelling Units per Hexagon

st_intersects() performs a spatial join between area_hexagon_grid and hdb_sf so that we can identify HDBs that are located in hexagons with bus stop.

apply() applies a function to each row. Inside the function, hdb_sf$total_dwelling_units[row] sums the total_dwelling_units values for all hdb_sf features that intersect with the hexagons.

hdbinhex  <-  st_intersects(area_hexagon_grid, 
                            hdb_sf)

area_hexagon_grid$TOT_DWELLINGUNITS <- 
  apply(hdbinhex, 1, function(row) {
    sum(hdb_sf$total_dwelling_units[row], na.rm = TRUE)
})

7. Combining Attributes with Flow Data

Two left_joins() will be performed between flow_data and area_hexagon_grid using the origin and destination grid IDs.

To perform the left join, we first have to convert grid_id of area_hexagon_grid into factor data type.

area_hexagon_grid$grid_id  <- as.factor(area_hexagon_grid$grid_id)
flowdata_ori <- flow_data %>% 
  left_join(area_hexagon_grid,
            by=c('ORIGIN_GRID' = 'grid_id')) %>% 
  rename(ORI_GEOM = geometry,
         ORI_BS = busstops,
         ORI_TRAINEXITS = COUNT_TRAINSTATIONEXIT,
         ORI_BIZ = COUNT_BIZ,
         ORI_FS = COUNT_FS,
         ORI_RECS = COUNT_RECS,
         ORI_RETAIL = COUNT_RETAIL,
         ORI_SCHOOLS = COUNT_SCHOOLS,
         ORI_HDBUNITS = TOT_DWELLINGUNITS)

glimpse(flowdata_ori)
Rows: 65,559
Columns: 17
$ ORIGIN_GRID    <fct> 21, 21, 21, 21, 21, 21, 40, 40, 40, 40, 40, 40, 40, 40,…
$ DESTIN_GRID    <fct> 61, 79, 116, 140, 159, 160, 21, 61, 78, 80, 116, 136, 1…
$ MORNING_PEAK   <dbl> 1, 1, 4, 3, 93, 1, 1, 2, 1, 2, 3, 1, 2, 40, 1, 1, 3, 2,…
$ ORIGIN_nBS     <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ ORIGIN_DESC    <chr> "AFT TUAS STH BLVD", "AFT TUAS STH BLVD", "AFT TUAS STH…
$ DESTIN_nBS     <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1…
$ DESTIN_DESC    <chr> "THE INDEX", "ABBOTT", "AFT TUAS STH ST 7", "BEF TUAS A…
$ dist           <dbl> 2704.163, 2250.000, 1984.313, 6873.864, 7611.669, 8842.…
$ ORI_GEOM       <POLYGON [m]> POLYGON ((3970.122 27348.13..., POLYGON ((3970.…
$ ORI_BS         <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2…
$ ORI_TRAINEXITS <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ ORI_BIZ        <int> 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4…
$ ORI_FS         <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ ORI_RECS       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ ORI_RETAIL     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ ORI_SCHOOLS    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
$ ORI_HDBUNITS   <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
flowdata_final <- flowdata_ori %>% 
  left_join(area_hexagon_grid,
            by=c('DESTIN_GRID' = 'grid_id')) %>% 
  rename(TRIPS = MORNING_PEAK,
        DEST_GEOM = geometry,
        DEST_BS = busstops,
        DEST_TRAINEXITS = COUNT_TRAINSTATIONEXIT,
        DEST_BIZ = COUNT_BIZ,
        DEST_FS = COUNT_FS,
        DEST_RECS = COUNT_RECS,
        DEST_RETAIL = COUNT_RETAIL,
        DEST_SCHOOLS = COUNT_SCHOOLS,
        DEST_HDBUNITS = TOT_DWELLINGUNITS) %>% 
 select(c(1:3,4,5,10:17,6:7,19:26,8)) %>% 
  select(-c('ORI_BS','DEST_BS'))

glimpse(flowdata_final)
Rows: 65,559
Columns: 22
$ ORIGIN_GRID     <fct> 21, 21, 21, 21, 21, 21, 40, 40, 40, 40, 40, 40, 40, 40…
$ DESTIN_GRID     <fct> 61, 79, 116, 140, 159, 160, 21, 61, 78, 80, 116, 136, …
$ TRIPS           <dbl> 1, 1, 4, 3, 93, 1, 1, 2, 1, 2, 3, 1, 2, 40, 1, 1, 3, 2…
$ ORIGIN_nBS      <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ ORIGIN_DESC     <chr> "AFT TUAS STH BLVD", "AFT TUAS STH BLVD", "AFT TUAS ST…
$ ORI_TRAINEXITS  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ ORI_BIZ         <int> 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, …
$ ORI_FS          <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ ORI_RECS        <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ ORI_RETAIL      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ ORI_SCHOOLS     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ ORI_HDBUNITS    <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ DESTIN_nBS      <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, …
$ DESTIN_DESC     <chr> "THE INDEX", "ABBOTT", "AFT TUAS STH ST 7", "BEF TUAS …
$ DEST_TRAINEXITS <int> 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, …
$ DEST_BIZ        <int> 50, 3, 6, 42, 44, 0, 0, 50, 3, 66, 6, 4, 42, 44, 50, 6…
$ DEST_FS         <int> 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, …
$ DEST_RECS       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ DEST_RETAIL     <int> 5, 0, 0, 3, 2, 0, 0, 5, 0, 5, 0, 0, 3, 2, 5, 5, 4, 0, …
$ DEST_SCHOOLS    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ DEST_HDBUNITS   <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …
$ dist            <dbl> 2704.163, 2250.000, 1984.313, 6873.864, 7611.669, 8842…

8 Preparing for Spatial Interaction Models

8.1 Visualising Distribution of Variables

Firstly, let us plot the distribution of the dependent variable (i.e. TRIPS) by using histogram method by using the code chunk below.

Notice that the distribution is highly right-skewed.

The code chunk below is used to create histograms for all origin and destination related variables. Then, ggarrange() is used to organised these histogram into a 3 columns by 3 rows of multiple small plots.

Origin Variables

Destination Variables

The distribution for the dependent variables are highly right-skewed as well.

Next, let us visualise the relation between the dependent variable and distance, which is one of the key independent variable in our Spatial Interaction Model.

The scatter plot shows that the relationship between trips and distance does not demonstrate a linear relationship. In contrast, if we plot the scatter plot by using the log transformed version of both variables, we can see that their relationship resembles more of an inverse linear relationship.

8.2 Poisson Regression

Poisson regression is appropriate for our dataset for two main reasons:

  • Count Dependent Variable: Our dependent variable (TRIPS) is a count (i.e., the number of occurrences of an event). Linear regression, on the other hand, assumes that the dependent variable is continuous and can take any value, including negative numbers, which is not applicable for count data. -

  • Predicting Non-Negative Values: Poisson regression naturally ensures that predictions are non-negative, which is essential for count data. Linear regression can predict negative values, which do not make sense for counts.

Since Poisson Regression is based of log and log 0 is undefined, it is important for us to ensure that no 0 values in the explanatory variables. In the code chunk below, summary() of Base R is used to compute the summary statistics of all variables in flowdata_final data frame.

summary(flowdata_final)
  ORIGIN_GRID     DESTIN_GRID        TRIPS           ORIGIN_nBS    
 1334   :  294   1334   :  355   Min.   :    1.0   Min.   : 1.000  
 1337   :  294   1314   :  336   1st Qu.:    7.0   1st Qu.: 1.000  
 1774   :  294   1372   :  325   Median :   38.0   Median : 2.000  
 1354   :  284   1337   :  296   Mean   :  383.1   Mean   : 2.011  
 1640   :  279   1352   :  296   3rd Qu.:  178.0   3rd Qu.: 2.000  
 1583   :  278   1296   :  290   Max.   :77433.0   Max.   :18.000  
 (Other):63836   (Other):63661                                     
 ORIGIN_DESC        ORI_TRAINEXITS      ORI_BIZ           ORI_FS      
 Length:65559       Min.   : 0.000   Min.   : 0.000   Min.   :  0.00  
 Class :character   1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:  1.00  
 Mode  :character   Median : 0.000   Median : 1.000   Median :  3.00  
                    Mean   : 1.258   Mean   : 6.513   Mean   :  7.21  
                    3rd Qu.: 2.000   3rd Qu.: 6.000   3rd Qu.:  8.00  
                    Max.   :13.000   Max.   :97.000   Max.   :130.00  
                                                                      
    ORI_RECS        ORI_RETAIL       ORI_SCHOOLS      ORI_HDBUNITS 
 Min.   : 0.000   Min.   :   0.00   Min.   :0.0000   Min.   :   0  
 1st Qu.: 0.000   1st Qu.:   7.00   1st Qu.:0.0000   1st Qu.:   0  
 Median : 1.000   Median :  28.00   Median :0.0000   Median : 932  
 Mean   : 2.166   Mean   :  88.66   Mean   :0.5586   Mean   :1847  
 3rd Qu.: 3.000   3rd Qu.:  94.00   3rd Qu.:1.0000   3rd Qu.:3351  
 Max.   :41.000   Max.   :1669.00   Max.   :4.0000   Max.   :7946  
                                                                   
   DESTIN_nBS     DESTIN_DESC        DEST_TRAINEXITS     DEST_BIZ     
 Min.   : 1.000   Length:65559       Min.   : 0.000   Min.   : 0.000  
 1st Qu.: 1.000   Class :character   1st Qu.: 0.000   1st Qu.: 0.000  
 Median : 2.000   Mode  :character   Median : 0.000   Median : 1.000  
 Mean   : 2.002                      Mean   : 1.353   Mean   : 7.302  
 3rd Qu.: 2.000                      3rd Qu.: 2.000   3rd Qu.: 6.000  
 Max.   :17.000                      Max.   :13.000   Max.   :97.000  
                                                                      
    DEST_FS          DEST_RECS       DEST_RETAIL      DEST_SCHOOLS   
 Min.   :  0.000   Min.   : 0.000   Min.   :   0.0   Min.   :0.0000  
 1st Qu.:  1.000   1st Qu.: 0.000   1st Qu.:   7.0   1st Qu.:0.0000  
 Median :  3.000   Median : 1.000   Median :  29.0   Median :0.0000  
 Mean   :  7.856   Mean   : 2.359   Mean   :  93.6   Mean   :0.5262  
 3rd Qu.:  9.000   3rd Qu.: 3.000   3rd Qu.: 102.0   3rd Qu.:1.0000  
 Max.   :130.000   Max.   :41.000   Max.   :1669.0   Max.   :4.0000  
                                                                     
 DEST_HDBUNITS       dist      
 Min.   :   0   Min.   :  100  
 1st Qu.:   0   1st Qu.: 2704  
 Median : 843   Median : 5408  
 Mean   :1731   Mean   : 6282  
 3rd Qu.:3126   3rd Qu.: 8842  
 Max.   :7946   Max.   :24784  
                               

The report above reveals that variables ORI_TRAINEXITS, ORI_BIZ, ORI_FS, ORI_RECS, ORI_RETAIL, ORI_SCHOOLS, ORI_HDBUNITS, DEST_TRAINEXITS, DEST_BIZ, DEST_FS, DEST_RECS, DEST_RETAIL, DEST_SCHOOLS, DEST_HDBUNITS consist of 0 values.

In view of this, code chunk below will be used to replace zero values to an arbitrary value of 0.99.

Show the code
# Origin Attributes

flowdata_final$ORI_TRAINEXITS <- ifelse(
  flowdata_final$ORI_TRAINEXITS == 0,
  0.99, 
  flowdata_final$ORI_TRAINEXITS)

flowdata_final$ORI_BIZ <- ifelse(
  flowdata_final$ORI_BIZ == 0,
  0.99, 
  flowdata_final$ORI_BIZ)

flowdata_final$ORI_FS <- ifelse(
  flowdata_final$ORI_FS == 0,
  0.99, 
  flowdata_final$ORI_FS)

flowdata_final$ORI_RECS <- ifelse(
  flowdata_final$ORI_RECS == 0,
  0.99, 
  flowdata_final$ORI_RECS)

flowdata_final$ORI_RETAIL <- ifelse(
  flowdata_final$ORI_RETAIL == 0,
  0.99, 
  flowdata_final$ORI_RETAIL)

flowdata_final$ORI_SCHOOLS <- ifelse(
  flowdata_final$ORI_SCHOOLS == 0,
  0.99, 
  flowdata_final$ORI_SCHOOLS)

flowdata_final$ORI_HDBUNITS <- ifelse(
  flowdata_final$ORI_HDBUNITS == 0,
  0.99, 
  flowdata_final$ORI_HDBUNITS)

# Destination Attributes

flowdata_final$DEST_TRAINEXITS <- ifelse(
  flowdata_final$DEST_TRAINEXITS == 0,
  0.99, 
  flowdata_final$DEST_TRAINEXITS)

flowdata_final$DEST_BIZ <- ifelse(
  flowdata_final$DEST_BIZ == 0,
  0.99, 
  flowdata_final$DEST_BIZ)

flowdata_final$DEST_FS <- ifelse(
  flowdata_final$DEST_FS == 0,
  0.99, 
  flowdata_final$DEST_FS)

flowdata_final$DEST_RECS <- ifelse(
  flowdata_final$DEST_RECS == 0,
  0.99, 
  flowdata_final$DEST_RECS)

flowdata_final$DEST_RETAIL <- ifelse(
  flowdata_final$DEST_RETAIL == 0,
  0.99, 
  flowdata_final$DEST_RETAIL)

flowdata_final$DEST_SCHOOLS <- ifelse(
  flowdata_final$DEST_SCHOOLS == 0,
  0.99, 
  flowdata_final$DEST_SCHOOLS)

flowdata_final$DEST_HDBUNITS <- ifelse(
  flowdata_final$DEST_HDBUNITS == 0,
  0.99, 
  flowdata_final$DEST_HDBUNITS)

We run summary() again to check the results.

summary(flowdata_final)
  ORIGIN_GRID     DESTIN_GRID        TRIPS           ORIGIN_nBS    
 1334   :  294   1334   :  355   Min.   :    1.0   Min.   : 1.000  
 1337   :  294   1314   :  336   1st Qu.:    7.0   1st Qu.: 1.000  
 1774   :  294   1372   :  325   Median :   38.0   Median : 2.000  
 1354   :  284   1337   :  296   Mean   :  383.1   Mean   : 2.011  
 1640   :  279   1352   :  296   3rd Qu.:  178.0   3rd Qu.: 2.000  
 1583   :  278   1296   :  290   Max.   :77433.0   Max.   :18.000  
 (Other):63836   (Other):63661                                     
 ORIGIN_DESC        ORI_TRAINEXITS      ORI_BIZ           ORI_FS       
 Length:65559       Min.   : 0.990   Min.   : 0.990   Min.   :  0.990  
 Class :character   1st Qu.: 0.990   1st Qu.: 0.990   1st Qu.:  1.000  
 Mode  :character   Median : 0.990   Median : 1.000   Median :  3.000  
                    Mean   : 1.886   Mean   : 6.959   Mean   :  7.447  
                    3rd Qu.: 2.000   3rd Qu.: 6.000   3rd Qu.:  8.000  
                    Max.   :13.000   Max.   :97.000   Max.   :130.000  
                                                                       
    ORI_RECS        ORI_RETAIL       ORI_SCHOOLS     ORI_HDBUNITS    
 Min.   : 0.990   Min.   :   0.99   Min.   :0.990   Min.   :   0.99  
 1st Qu.: 0.990   1st Qu.:   7.00   1st Qu.:0.990   1st Qu.:   0.99  
 Median : 1.000   Median :  28.00   Median :0.990   Median : 932.00  
 Mean   : 2.572   Mean   :  88.73   Mean   :1.181   Mean   :1847.21  
 3rd Qu.: 3.000   3rd Qu.:  94.00   3rd Qu.:1.000   3rd Qu.:3351.00  
 Max.   :41.000   Max.   :1669.00   Max.   :4.000   Max.   :7946.00  
                                                                     
   DESTIN_nBS     DESTIN_DESC        DEST_TRAINEXITS     DEST_BIZ    
 Min.   : 1.000   Length:65559       Min.   : 0.990   Min.   : 0.99  
 1st Qu.: 1.000   Class :character   1st Qu.: 0.990   1st Qu.: 0.99  
 Median : 2.000   Mode  :character   Median : 0.990   Median : 1.00  
 Mean   : 2.002                      Mean   : 1.975   Mean   : 7.73  
 3rd Qu.: 2.000                      3rd Qu.: 2.000   3rd Qu.: 6.00  
 Max.   :17.000                      Max.   :13.000   Max.   :97.00  
                                                                     
    DEST_FS          DEST_RECS       DEST_RETAIL       DEST_SCHOOLS  
 Min.   :  0.990   Min.   : 0.990   Min.   :   0.99   Min.   :0.990  
 1st Qu.:  1.000   1st Qu.: 0.990   1st Qu.:   7.00   1st Qu.:0.990  
 Median :  3.000   Median : 1.000   Median :  29.00   Median :0.990  
 Mean   :  8.095   Mean   : 2.761   Mean   :  93.67   Mean   :1.167  
 3rd Qu.:  9.000   3rd Qu.: 3.000   3rd Qu.: 102.00   3rd Qu.:1.000  
 Max.   :130.000   Max.   :41.000   Max.   :1669.00   Max.   :4.000  
                                                                     
 DEST_HDBUNITS          dist      
 Min.   :   0.99   Min.   :  100  
 1st Qu.:   0.99   1st Qu.: 2704  
 Median : 843.00   Median : 5408  
 Mean   :1731.58   Mean   : 6282  
 3rd Qu.:3126.00   3rd Qu.: 8842  
 Max.   :7946.00   Max.   :24784  
                                  

8.3 Preparing Inter-Zonal Flow Data

In general, we will calibrate separate Spatial Interaction Models for inter- and intra-zonal flows. In our analysis, we will focus our attention on inter-zonal flows. Therefore, it is necessary to exclude intra-zonal flows from the flow_data.

First, two new columns called FlowNoIntra and offset will be created by using the code chunk below.

flowdata_final$FlowNoIntra <- ifelse(
  flowdata_final$ORIGIN_GRID == flowdata_final$DESTIN_GRID, 
  0, 
  flowdata_final$TRIPS)
flowdata_final$offset <- ifelse(
  flowdata_final$ORIGIN_GRID == flowdata_final$DESTIN_GRID, 
  0.000001, 
  1)

According to the syntax used to derive values in FlowNoIntra field, all intra-zonal flow will be given a value of 0 or else the original flow values will be inserted.

Next, inter-zonal flow will be selected from flow_data and save into a new output data.frame called inter_zonal_flow by using the code chunk below.

interzonal_flow <- flowdata_final %>%
  filter(FlowNoIntra > 0)

There are 64,935 interzonal flows in our dataset.

8.4 Correlation Analysis

Before building a Poisson regression model, it is important to ensure that the indepdent variables used are not highly correlated to each other. Multicollinearity in a regression model can compromise the quality of the model.

The code chunk below uses the corrplot package to plot a scatterplot matrix of the relationship between the independent variables in interzonal_flow data.frame. In the code chunk above, AOE order is used. It orders the variables by using the angular order of the eigenvectors method suggested by Michael Friendly.

From the scatterplot matrix, it is observed that none of the variable pairs exhibit a correlation greater than 0.8. Consequently, with no issues of multicollinearity present, there is no need to exclude any variables from our analysis.

9 Calibrating Spatial Interaction Models

In this section, we will be calibrating spatial interaction models using glm() of Base Stats.

uncSIM <- glm(formula = TRIPS ~ 
                log(ORI_TRAINEXITS) +
                log(ORI_BIZ) +
                log(ORI_FS) +
                log(ORI_RECS) +
                log(ORI_RETAIL) +
                log(ORI_SCHOOLS) +
                log(ORI_HDBUNITS) +
                log(DEST_TRAINEXITS) +
                log(DEST_BIZ) +
                log(DEST_FS) +
                log(DEST_RECS) +
                log(DEST_RETAIL) +
                log(DEST_SCHOOLS) +
                log(DEST_HDBUNITS) +
                log(dist),
              family = poisson(link = "log"),
              data = interzonal_flow,
              na.action = na.exclude) # excludes any NAs in the data

summary(uncSIM)

Call:
glm(formula = TRIPS ~ log(ORI_TRAINEXITS) + log(ORI_BIZ) + log(ORI_FS) + 
    log(ORI_RECS) + log(ORI_RETAIL) + log(ORI_SCHOOLS) + log(ORI_HDBUNITS) + 
    log(DEST_TRAINEXITS) + log(DEST_BIZ) + log(DEST_FS) + log(DEST_RECS) + 
    log(DEST_RETAIL) + log(DEST_SCHOOLS) + log(DEST_HDBUNITS) + 
    log(dist), family = poisson(link = "log"), data = interzonal_flow, 
    na.action = na.exclude)

Coefficients:
                       Estimate Std. Error  z value Pr(>|z|)    
(Intercept)           1.606e+01  2.068e-03  7763.96   <2e-16 ***
log(ORI_TRAINEXITS)   1.723e-01  3.908e-04   440.81   <2e-16 ***
log(ORI_BIZ)         -1.540e-01  2.349e-04  -655.45   <2e-16 ***
log(ORI_FS)           1.379e-01  3.706e-04   372.05   <2e-16 ***
log(ORI_RECS)        -2.300e-01  3.519e-04  -653.50   <2e-16 ***
log(ORI_RETAIL)       9.938e-03  2.317e-04    42.88   <2e-16 ***
log(ORI_SCHOOLS)      7.494e-03  6.302e-04    11.89   <2e-16 ***
log(ORI_HDBUNITS)     1.565e-01  8.668e-05  1804.83   <2e-16 ***
log(DEST_TRAINEXITS)  4.546e-01  3.748e-04  1212.93   <2e-16 ***
log(DEST_BIZ)         7.170e-02  2.050e-04   349.80   <2e-16 ***
log(DEST_FS)          2.588e-01  3.666e-04   705.82   <2e-16 ***
log(DEST_RECS)       -3.641e-01  3.463e-04 -1051.35   <2e-16 ***
log(DEST_RETAIL)      4.111e-02  2.208e-04   186.17   <2e-16 ***
log(DEST_SCHOOLS)     2.479e-01  6.665e-04   371.90   <2e-16 ***
log(DEST_HDBUNITS)   -6.394e-03  7.058e-05   -90.59   <2e-16 ***
log(dist)            -1.465e+00  2.546e-04 -5752.95   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 96655476  on 64935  degrees of freedom
Residual deviance: 45405176  on 64920  degrees of freedom
AIC: 45761795

Number of Fisher Scoring iterations: 6
orcSIM <- glm(formula = TRIPS ~ 
                ORIGIN_GRID,
                log(ORI_TRAINEXITS) +
                log(ORI_BIZ) +
                log(ORI_FS) +
                log(ORI_RECS) +
                log(ORI_RETAIL) +
                log(ORI_SCHOOLS) +
                log(ORI_HDBUNITS) +
                #log(DEST_TRAINEXITS) +
                #log(DEST_BIZ) +
                #log(DEST_FS) +
                #log(DEST_RECS) +
                #log(DEST_RETAIL) +
                #log(DEST_SCHOOLS) +
                #log(DEST_HDBUNITS) +
                log(dist) - 1,
              family = poisson(link = "log"),
              data = interzonal_flow,
              na.action = na.exclude) # excludes any NAs in the data

summary(orcSIM)

Call:
glm(formula = TRIPS ~ ORIGIN_GRID, family = poisson(link = "log"), 
    data = interzonal_flow, weights = log(ORI_TRAINEXITS) + log(ORI_BIZ) + 
        log(ORI_FS) + log(ORI_RECS) + log(ORI_RETAIL) + log(ORI_SCHOOLS) + 
        log(ORI_HDBUNITS) + log(dist) - 1, na.action = na.exclude)

Coefficients:
                  Estimate Std. Error z value Pr(>|z|)    
(Intercept)      2.9115022  0.0352997  82.479  < 2e-16 ***
ORIGIN_GRID40   -0.9354880  0.0579605 -16.140  < 2e-16 ***
ORIGIN_GRID42   -0.1678678  0.0460024  -3.649 0.000263 ***
ORIGIN_GRID60   -0.2628750  0.0573182  -4.586 4.51e-06 ***
ORIGIN_GRID61    1.4292075  0.0359705  39.733  < 2e-16 ***
ORIGIN_GRID62   -0.9022944  0.0542986 -16.617  < 2e-16 ***
ORIGIN_GRID78    0.1742171  0.0431962   4.033 5.50e-05 ***
ORIGIN_GRID79    0.2051530  0.0447937   4.580 4.65e-06 ***
ORIGIN_GRID80    1.8773478  0.0356671  52.635  < 2e-16 ***
ORIGIN_GRID81    0.8054066  0.0384866  20.927  < 2e-16 ***
ORIGIN_GRID82   -0.6317187  0.0559767 -11.285  < 2e-16 ***
ORIGIN_GRID99   -0.0522788  0.0475912  -1.098 0.271987    
ORIGIN_GRID100   0.4393492  0.0416678  10.544  < 2e-16 ***
ORIGIN_GRID101   3.0834364  0.0354471  86.987  < 2e-16 ***
ORIGIN_GRID102  -0.7378842  0.0426727 -17.292  < 2e-16 ***
ORIGIN_GRID116   2.3600096  0.0360389  65.485  < 2e-16 ***
ORIGIN_GRID117  -0.6503117  0.0701282  -9.273  < 2e-16 ***
ORIGIN_GRID118   0.1754458  0.0400472   4.381 1.18e-05 ***
ORIGIN_GRID119   0.9787422  0.0370827  26.393  < 2e-16 ***
ORIGIN_GRID120   0.4501903  0.0380200  11.841  < 2e-16 ***
ORIGIN_GRID121   0.1021596  0.0372894   2.740 0.006151 ** 
ORIGIN_GRID122   2.4148465  0.0363888  66.362  < 2e-16 ***
ORIGIN_GRID136   2.5964020  0.0359084  72.306  < 2e-16 ***
ORIGIN_GRID137   0.2104305  0.0401806   5.237 1.63e-07 ***
ORIGIN_GRID138   0.3604335  0.0473757   7.608 2.78e-14 ***
ORIGIN_GRID139   0.9464320  0.0390505  24.236  < 2e-16 ***
ORIGIN_GRID140   3.3906434  0.0353924  95.802  < 2e-16 ***
ORIGIN_GRID141   0.1528215  0.0366967   4.164 3.12e-05 ***
ORIGIN_GRID142   1.0798661  0.0383132  28.185  < 2e-16 ***
ORIGIN_GRID156   1.1403587  0.0438462  26.008  < 2e-16 ***
ORIGIN_GRID158   0.8657202  0.0381108  22.716  < 2e-16 ***
ORIGIN_GRID159   2.8732552  0.0354294  81.098  < 2e-16 ***
ORIGIN_GRID160   3.4352098  0.0353679  97.128  < 2e-16 ***
ORIGIN_GRID177   0.2730368  0.0448293   6.091 1.12e-09 ***
ORIGIN_GRID178   0.1246892  0.0374842   3.326 0.000880 ***
ORIGIN_GRID179  -0.5436542  0.0505509 -10.755  < 2e-16 ***
ORIGIN_GRID195   0.2421465  0.0458082   5.286 1.25e-07 ***
ORIGIN_GRID196   4.6026449  0.0353296 130.277  < 2e-16 ***
ORIGIN_GRID197   1.7166196  0.0358066  47.941  < 2e-16 ***
ORIGIN_GRID215  -0.5503296  0.0566753  -9.710  < 2e-16 ***
ORIGIN_GRID216   0.2705818  0.0381136   7.099 1.25e-12 ***
ORIGIN_GRID217  -0.8317703  0.0642557 -12.945  < 2e-16 ***
ORIGIN_GRID233   0.4459287  0.0400808  11.126  < 2e-16 ***
ORIGIN_GRID234   1.1919655  0.0363238  32.815  < 2e-16 ***
ORIGIN_GRID235   0.7820283  0.0374326  20.892  < 2e-16 ***
ORIGIN_GRID252   1.7179247  0.0370386  46.382  < 2e-16 ***
ORIGIN_GRID253   0.4425143  0.0375683  11.779  < 2e-16 ***
ORIGIN_GRID254   0.3591383  0.0381829   9.406  < 2e-16 ***
ORIGIN_GRID270  -1.3395383  0.1325074 -10.109  < 2e-16 ***
ORIGIN_GRID271   0.9661627  0.0380565  25.388  < 2e-16 ***
ORIGIN_GRID272   3.2360198  0.0354038  91.403  < 2e-16 ***
ORIGIN_GRID290   0.6923305  0.0399221  17.342  < 2e-16 ***
ORIGIN_GRID291   1.7147805  0.0403238  42.525  < 2e-16 ***
ORIGIN_GRID292   0.8501471  0.0383825  22.149  < 2e-16 ***
ORIGIN_GRID308   2.1642787  0.0362303  59.737  < 2e-16 ***
ORIGIN_GRID309   0.8886090  0.0377560  23.536  < 2e-16 ***
ORIGIN_GRID310   0.9487545  0.0372197  25.491  < 2e-16 ***
ORIGIN_GRID329   2.3350564  0.0369783  63.147  < 2e-16 ***
ORIGIN_GRID330   1.6558814  0.0360417  45.943  < 2e-16 ***
ORIGIN_GRID347   1.1952289  0.0365200  32.728  < 2e-16 ***
ORIGIN_GRID348   0.3791141  0.0385684   9.830  < 2e-16 ***
ORIGIN_GRID349   2.1155657  0.0383274  55.197  < 2e-16 ***
ORIGIN_GRID366   2.1102228  0.0368270  57.301  < 2e-16 ***
ORIGIN_GRID367   1.0523327  0.0378759  27.784  < 2e-16 ***
ORIGIN_GRID368   4.6779795  0.0353049 132.502  < 2e-16 ***
ORIGIN_GRID369   1.7186535  0.0394107  43.609  < 2e-16 ***
ORIGIN_GRID370   2.1939944  0.0360186  60.913  < 2e-16 ***
ORIGIN_GRID385   0.0142031  0.0462827   0.307 0.758938    
ORIGIN_GRID386   1.3350659  0.0366548  36.423  < 2e-16 ***
ORIGIN_GRID387  -0.1026565  0.0373668  -2.747 0.006009 ** 
ORIGIN_GRID388   0.8408282  0.0428909  19.604  < 2e-16 ***
ORIGIN_GRID389   2.5521657  0.0364691  69.982  < 2e-16 ***
ORIGIN_GRID404   0.8707745  0.0399326  21.806  < 2e-16 ***
ORIGIN_GRID405   0.7571928  0.0388891  19.471  < 2e-16 ***
ORIGIN_GRID406   1.2669532  0.0361533  35.044  < 2e-16 ***
ORIGIN_GRID407   4.1761713  0.0353337 118.192  < 2e-16 ***
ORIGIN_GRID408   2.4852565  0.0359633  69.105  < 2e-16 ***
ORIGIN_GRID424   1.7670904  0.0363642  48.594  < 2e-16 ***
ORIGIN_GRID425   1.5151965  0.0356452  42.508  < 2e-16 ***
ORIGIN_GRID426   4.6694664  0.0353147 132.225  < 2e-16 ***
ORIGIN_GRID427   3.3771911  0.0358311  94.253  < 2e-16 ***
ORIGIN_GRID442   0.9259157  0.0405229  22.849  < 2e-16 ***
ORIGIN_GRID443  -1.1996534  0.0929555 -12.906  < 2e-16 ***
ORIGIN_GRID444   2.8837514  0.0354353  81.381  < 2e-16 ***
ORIGIN_GRID445   3.5092750  0.0353366  99.310  < 2e-16 ***
ORIGIN_GRID447  -1.5752628  0.0629587 -25.021  < 2e-16 ***
ORIGIN_GRID448   0.2968449  0.0415247   7.149 8.77e-13 ***
ORIGIN_GRID461   1.4495189  0.0368830  39.300  < 2e-16 ***
ORIGIN_GRID462   1.9695844  0.0360354  54.657  < 2e-16 ***
ORIGIN_GRID463   2.4211465  0.0353809  68.431  < 2e-16 ***
ORIGIN_GRID464   4.5023091  0.0353056 127.524  < 2e-16 ***
ORIGIN_GRID465   1.6399335  0.0362948  45.184  < 2e-16 ***
ORIGIN_GRID466   1.1271205  0.0378436  29.784  < 2e-16 ***
ORIGIN_GRID467  -1.4895176  0.0621648 -23.961  < 2e-16 ***
ORIGIN_GRID480   0.3900632  0.0441020   8.845  < 2e-16 ***
ORIGIN_GRID481   1.9215357  0.0359613  53.433  < 2e-16 ***
ORIGIN_GRID482   1.1821893  0.0358260  32.998  < 2e-16 ***
ORIGIN_GRID483   4.3808045  0.0353061 124.081  < 2e-16 ***
ORIGIN_GRID484   4.5626522  0.0353075 129.226  < 2e-16 ***
ORIGIN_GRID486   1.0877865  0.0365133  29.792  < 2e-16 ***
ORIGIN_GRID487  -1.3695269  0.0615157 -22.263  < 2e-16 ***
ORIGIN_GRID488  -1.5130364  0.0839711 -18.019  < 2e-16 ***
ORIGIN_GRID489  -2.9115022  0.2330378 -12.494  < 2e-16 ***
ORIGIN_GRID499   0.9431739  0.0399625  23.601  < 2e-16 ***
ORIGIN_GRID500   3.0790166  0.0375433  82.012  < 2e-16 ***
ORIGIN_GRID501   1.5586693  0.0356798  43.685  < 2e-16 ***
ORIGIN_GRID502   4.4198853  0.0353087 125.179  < 2e-16 ***
ORIGIN_GRID503   3.8457565  0.0353384 108.826  < 2e-16 ***
ORIGIN_GRID507  -0.5215581  0.0495435 -10.527  < 2e-16 ***
ORIGIN_GRID508   0.6514829  0.0392716  16.589  < 2e-16 ***
ORIGIN_GRID518  -1.4688359  0.0839206 -17.503  < 2e-16 ***
ORIGIN_GRID519   1.1072620  0.0376591  29.402  < 2e-16 ***
ORIGIN_GRID520   1.9892095  0.0368710  53.951  < 2e-16 ***
ORIGIN_GRID521   4.4664831  0.0353013 126.525  < 2e-16 ***
ORIGIN_GRID522   3.9524059  0.0353208 111.900  < 2e-16 ***
ORIGIN_GRID524  -0.8082773  0.0533514 -15.150  < 2e-16 ***
ORIGIN_GRID528  -0.6258425  0.0535983 -11.677  < 2e-16 ***
ORIGIN_GRID529  -1.6814393  0.0799325 -21.036  < 2e-16 ***
ORIGIN_GRID530   0.3450509  0.0395348   8.728  < 2e-16 ***
ORIGIN_GRID537   0.4127821  0.0392807  10.509  < 2e-16 ***
ORIGIN_GRID538   2.1338372  0.0361122  59.089  < 2e-16 ***
ORIGIN_GRID539   1.2766771  0.0357423  35.719  < 2e-16 ***
ORIGIN_GRID540   3.3535806  0.0353124  94.969  < 2e-16 ***
ORIGIN_GRID541   0.9110114  0.0425678  21.401  < 2e-16 ***
ORIGIN_GRID547  -0.8293441  0.0523837 -15.832  < 2e-16 ***
ORIGIN_GRID548  -2.3310671  0.0937234 -24.872  < 2e-16 ***
ORIGIN_GRID557   0.3648067  0.0377832   9.655  < 2e-16 ***
ORIGIN_GRID558   1.4640137  0.0362522  40.384  < 2e-16 ***
ORIGIN_GRID559   1.9861854  0.0356674  55.686  < 2e-16 ***
ORIGIN_GRID560   3.7486612  0.0353071 106.173  < 2e-16 ***
ORIGIN_GRID562   0.6957275  0.0372809  18.662  < 2e-16 ***
ORIGIN_GRID577   1.0729916  0.0368547  29.114  < 2e-16 ***
ORIGIN_GRID578   3.4346110  0.0353120  97.265  < 2e-16 ***
ORIGIN_GRID595   2.0847966  0.0356299  58.512  < 2e-16 ***
ORIGIN_GRID596   2.5405440  0.0353288  71.911  < 2e-16 ***
ORIGIN_GRID597   3.2187810  0.0353165  91.141  < 2e-16 ***
ORIGIN_GRID598   4.0118197  0.0353049 113.634  < 2e-16 ***
ORIGIN_GRID600   3.6625240  0.0353941 103.478  < 2e-16 ***
ORIGIN_GRID613   1.9987868  0.0358294  55.786  < 2e-16 ***
ORIGIN_GRID614   0.1740243  0.0376110   4.627 3.71e-06 ***
ORIGIN_GRID615   3.8253130  0.0353064 108.346  < 2e-16 ***
ORIGIN_GRID616   4.1657248  0.0353070 117.986  < 2e-16 ***
ORIGIN_GRID617   4.0497416  0.0353578 114.536  < 2e-16 ***
ORIGIN_GRID633   1.6413829  0.0358567  45.776  < 2e-16 ***
ORIGIN_GRID634   2.6630393  0.0353230  75.391  < 2e-16 ***
ORIGIN_GRID635   3.3077728  0.0353294  93.627  < 2e-16 ***
ORIGIN_GRID636   3.8506513  0.0353057 109.066  < 2e-16 ***
ORIGIN_GRID638   0.8346093  0.0371536  22.464  < 2e-16 ***
ORIGIN_GRID654   2.2020227  0.0355473  61.946  < 2e-16 ***
ORIGIN_GRID657   0.3870870  0.0386254  10.022  < 2e-16 ***
ORIGIN_GRID671   2.1684161  0.0355942  60.920  < 2e-16 ***
ORIGIN_GRID673   1.8682963  0.0354462  52.708  < 2e-16 ***
ORIGIN_GRID674   3.3025722  0.0353122  93.525  < 2e-16 ***
ORIGIN_GRID689   1.7663604  0.0361343  48.883  < 2e-16 ***
ORIGIN_GRID690   3.4754515  0.0353365  98.353  < 2e-16 ***
ORIGIN_GRID691   0.3534478  0.0364107   9.707  < 2e-16 ***
ORIGIN_GRID692   3.6733876  0.0353055 104.046  < 2e-16 ***
ORIGIN_GRID693   3.3547705  0.0353659  94.859  < 2e-16 ***
ORIGIN_GRID695   4.6715956  0.0353080 132.310  < 2e-16 ***
ORIGIN_GRID700  -0.3404395  0.0438457  -7.764 8.20e-15 ***
ORIGIN_GRID710   0.5378826  0.0357934  15.027  < 2e-16 ***
ORIGIN_GRID711   2.9863282  0.0353110  84.572  < 2e-16 ***
ORIGIN_GRID712   2.6845251  0.0353282  75.988  < 2e-16 ***
ORIGIN_GRID713   3.5727627  0.0353500 101.068  < 2e-16 ***
ORIGIN_GRID714   4.6927230  0.0353242 132.847  < 2e-16 ***
ORIGIN_GRID715   3.6151445  0.0354059 102.106  < 2e-16 ***
ORIGIN_GRID727   0.5223860  0.0396476  13.176  < 2e-16 ***
ORIGIN_GRID728   3.7582634  0.0353093 106.438  < 2e-16 ***
ORIGIN_GRID729   3.3454069  0.0353061  94.754  < 2e-16 ***
ORIGIN_GRID730   3.4414621  0.0353114  97.460  < 2e-16 ***
ORIGIN_GRID731   5.2281869  0.0353143 148.047  < 2e-16 ***
ORIGIN_GRID732   2.9401055  0.0354358  82.970  < 2e-16 ***
ORIGIN_GRID733   3.8351850  0.0353064 108.626  < 2e-16 ***
ORIGIN_GRID734   5.0935164  0.0353200 144.210  < 2e-16 ***
ORIGIN_GRID738   1.4690860  0.0363909  40.370  < 2e-16 ***
ORIGIN_GRID746   1.0032295  0.0371491  27.005  < 2e-16 ***
ORIGIN_GRID748   1.3781030  0.0353933  38.937  < 2e-16 ***
ORIGIN_GRID749   3.5598469  0.0353070 100.826  < 2e-16 ***
ORIGIN_GRID750   3.5105650  0.0353069  99.430  < 2e-16 ***
ORIGIN_GRID751   3.7685500  0.0353137 106.716  < 2e-16 ***
ORIGIN_GRID752   4.9937619  0.0353191 141.390  < 2e-16 ***
ORIGIN_GRID753   3.9704535  0.0353032 112.467  < 2e-16 ***
ORIGIN_GRID754   4.9088265  0.0353200 138.981  < 2e-16 ***
ORIGIN_GRID757   1.3785532  0.0363317  37.944  < 2e-16 ***
ORIGIN_GRID764  -0.3529062  0.0442430  -7.977 1.50e-15 ***
ORIGIN_GRID766   2.6310060  0.0353199  74.491  < 2e-16 ***
ORIGIN_GRID767   1.9104511  0.0353795  53.999  < 2e-16 ***
ORIGIN_GRID768   3.4120563  0.0353129  96.624  < 2e-16 ***
ORIGIN_GRID769   2.5384888  0.0353421  71.826  < 2e-16 ***
ORIGIN_GRID770   3.1601523  0.0353198  89.473  < 2e-16 ***
ORIGIN_GRID771   3.3779058  0.0353109  95.662  < 2e-16 ***
ORIGIN_GRID772   4.9296282  0.0353273 139.542  < 2e-16 ***
ORIGIN_GRID773   6.4559559  0.0353089 182.842  < 2e-16 ***
ORIGIN_GRID774   1.7760066  0.0360050  49.327  < 2e-16 ***
ORIGIN_GRID775   0.7550890  0.0371581  20.321  < 2e-16 ***
ORIGIN_GRID776   2.3347275  0.0357594  65.290  < 2e-16 ***
ORIGIN_GRID784   1.2724548  0.0365082  34.854  < 2e-16 ***
ORIGIN_GRID785   1.6358828  0.0354310  46.171  < 2e-16 ***
ORIGIN_GRID786   0.8340358  0.0355995  23.428  < 2e-16 ***
ORIGIN_GRID787   4.5373704  0.0353355 128.408  < 2e-16 ***
ORIGIN_GRID788   3.7474365  0.0353035 106.149  < 2e-16 ***
ORIGIN_GRID789   4.4125308  0.0353185 124.935  < 2e-16 ***
ORIGIN_GRID790   1.8716138  0.0355211  52.690  < 2e-16 ***
ORIGIN_GRID791   2.4850883  0.0353783  70.243  < 2e-16 ***
ORIGIN_GRID792   2.3278521  0.0353505  65.851  < 2e-16 ***
ORIGIN_GRID793  -0.2307216  0.0406271  -5.679 1.35e-08 ***
ORIGIN_GRID794   1.1375552  0.0364574  31.202  < 2e-16 ***
ORIGIN_GRID795   0.9577905  0.0375542  25.504  < 2e-16 ***
ORIGIN_GRID803   1.8370958  0.0354760  51.784  < 2e-16 ***
ORIGIN_GRID804   2.5147454  0.0353741  71.090  < 2e-16 ***
ORIGIN_GRID805   0.5637399  0.0366276  15.391  < 2e-16 ***
ORIGIN_GRID806   3.4635540  0.0353063  98.100  < 2e-16 ***
ORIGIN_GRID807   4.4887393  0.0353949 126.819  < 2e-16 ***
ORIGIN_GRID809   3.3683555  0.0353081  95.399  < 2e-16 ***
ORIGIN_GRID810   1.5236885  0.0355337  42.880  < 2e-16 ***
ORIGIN_GRID811   1.0533558  0.0356581  29.540  < 2e-16 ***
ORIGIN_GRID812   0.4161079  0.0364269  11.423  < 2e-16 ***
ORIGIN_GRID813  -0.0017214  0.0437458  -0.039 0.968611    
ORIGIN_GRID814   1.4339387  0.0362972  39.505  < 2e-16 ***
ORIGIN_GRID822   2.5826772  0.0354013  72.954  < 2e-16 ***
ORIGIN_GRID823   2.5060286  0.0353201  70.952  < 2e-16 ***
ORIGIN_GRID824   0.9360091  0.0357987  26.146  < 2e-16 ***
ORIGIN_GRID825   2.2104622  0.0353636  62.507  < 2e-16 ***
ORIGIN_GRID826   3.0578625  0.0353089  86.603  < 2e-16 ***
ORIGIN_GRID829   3.2838609  0.0353115  92.997  < 2e-16 ***
ORIGIN_GRID831   2.4374913  0.0353476  68.958  < 2e-16 ***
ORIGIN_GRID832  -0.1170273  0.0378643  -3.091 0.001997 ** 
ORIGIN_GRID833   2.5301956  0.0354133  71.448  < 2e-16 ***
ORIGIN_GRID840   1.8740871  0.0356171  52.618  < 2e-16 ***
ORIGIN_GRID841   3.0413052  0.0353112  86.129  < 2e-16 ***
ORIGIN_GRID842   3.4148552  0.0353049  96.725  < 2e-16 ***
ORIGIN_GRID843   1.2163354  0.0358690  33.910  < 2e-16 ***
ORIGIN_GRID844   1.2299919  0.0355610  34.588  < 2e-16 ***
ORIGIN_GRID845   3.0761432  0.0353324  87.063  < 2e-16 ***
ORIGIN_GRID846   0.4461329  0.0358636  12.440  < 2e-16 ***
ORIGIN_GRID847   3.5508668  0.0353032 100.582  < 2e-16 ***
ORIGIN_GRID850  -1.4877547  0.0930623 -15.987  < 2e-16 ***
ORIGIN_GRID851   3.8781527  0.0353136 109.820  < 2e-16 ***
ORIGIN_GRID852  -0.0817390  0.0428817  -1.906 0.056631 .  
ORIGIN_GRID859   1.2915222  0.0355113  36.369  < 2e-16 ***
ORIGIN_GRID860   3.3129973  0.0353125  93.819  < 2e-16 ***
ORIGIN_GRID861   3.9258654  0.0353019 111.208  < 2e-16 ***
ORIGIN_GRID862   1.7293143  0.0358396  48.252  < 2e-16 ***
ORIGIN_GRID863   2.7069438  0.0354294  76.404  < 2e-16 ***
ORIGIN_GRID864   0.6081382  0.0358039  16.985  < 2e-16 ***
ORIGIN_GRID865   2.4306725  0.0353330  68.793  < 2e-16 ***
ORIGIN_GRID866   1.0973523  0.0354019  30.997  < 2e-16 ***
ORIGIN_GRID867   4.3431412  0.0353211 122.962  < 2e-16 ***
ORIGIN_GRID869   1.0501180  0.0402843  26.068  < 2e-16 ***
ORIGIN_GRID871   0.6532616  0.0369126  17.698  < 2e-16 ***
ORIGIN_GRID872  -2.9115022  0.4017821  -7.246 4.28e-13 ***
ORIGIN_GRID878   1.7698968  0.0353878  50.014  < 2e-16 ***
ORIGIN_GRID879   3.0067036  0.0353088  85.154  < 2e-16 ***
ORIGIN_GRID880   2.8716626  0.0353129  81.320  < 2e-16 ***
ORIGIN_GRID882   2.2617652  0.0353779  63.932  < 2e-16 ***
ORIGIN_GRID883   1.7933834  0.0354287  50.620  < 2e-16 ***
ORIGIN_GRID884   0.4638894  0.0357446  12.978  < 2e-16 ***
ORIGIN_GRID885   3.6440043  0.0353071 103.209  < 2e-16 ***
ORIGIN_GRID886   3.8818576  0.0353412 109.839  < 2e-16 ***
ORIGIN_GRID890   1.6268241  0.0356241  45.666  < 2e-16 ***
ORIGIN_GRID891   4.6956070  0.0353115 132.977  < 2e-16 ***
ORIGIN_GRID897   1.6777204  0.0354392  47.341  < 2e-16 ***
ORIGIN_GRID898   2.3209785  0.0353383  65.679  < 2e-16 ***
ORIGIN_GRID899   1.8875987  0.0353379  53.416  < 2e-16 ***
ORIGIN_GRID900   1.3604416  0.0354141  38.415  < 2e-16 ***
ORIGIN_GRID901   2.8347589  0.0353186  80.263  < 2e-16 ***
ORIGIN_GRID902   2.0040879  0.0354026  56.608  < 2e-16 ***
ORIGIN_GRID903   2.3688348  0.0372500  63.593  < 2e-16 ***
ORIGIN_GRID904   3.6444584  0.0353092 103.215  < 2e-16 ***
ORIGIN_GRID905   4.4739115  0.0353167 126.680  < 2e-16 ***
ORIGIN_GRID907   1.3066579  0.0365919  35.709  < 2e-16 ***
ORIGIN_GRID909   3.2284688  0.0353085  91.436  < 2e-16 ***
ORIGIN_GRID910   4.6021802  0.0353040 130.359  < 2e-16 ***
ORIGIN_GRID915   0.4780194  0.0362213  13.197  < 2e-16 ***
ORIGIN_GRID916   0.5173983  0.0369055  14.020  < 2e-16 ***
ORIGIN_GRID917   0.9242837  0.0356443  25.931  < 2e-16 ***
ORIGIN_GRID918   1.4174306  0.0355283  39.896  < 2e-16 ***
ORIGIN_GRID919   0.6517020  0.0356232  18.294  < 2e-16 ***
ORIGIN_GRID920   1.9477952  0.0353339  55.125  < 2e-16 ***
ORIGIN_GRID922   2.8347212  0.0354816  79.893  < 2e-16 ***
ORIGIN_GRID923   4.2290668  0.0353117 119.764  < 2e-16 ***
ORIGIN_GRID927   4.0120516  0.0353838 113.387  < 2e-16 ***
ORIGIN_GRID928   4.4871746  0.0353108 127.076  < 2e-16 ***
ORIGIN_GRID929   0.2568753  0.0404525   6.350 2.15e-10 ***
ORIGIN_GRID935   1.5145511  0.0354346  42.742  < 2e-16 ***
ORIGIN_GRID936   2.2522193  0.0353504  63.711  < 2e-16 ***
ORIGIN_GRID937   2.8767249  0.0353378  81.407  < 2e-16 ***
ORIGIN_GRID938   0.8150163  0.0356942  22.833  < 2e-16 ***
ORIGIN_GRID939   1.7446957  0.0353419  49.366  < 2e-16 ***
ORIGIN_GRID945   1.0811732  0.0365091  29.614  < 2e-16 ***
ORIGIN_GRID947   3.1806957  0.0353107  90.077  < 2e-16 ***
ORIGIN_GRID948   3.6853890  0.0353137 104.361  < 2e-16 ***
ORIGIN_GRID953   2.6619789  0.0353330  75.340  < 2e-16 ***
ORIGIN_GRID954   2.2279055  0.0353626  63.002  < 2e-16 ***
ORIGIN_GRID955   2.8506829  0.0353193  80.712  < 2e-16 ***
ORIGIN_GRID956   1.7491206  0.0354299  49.368  < 2e-16 ***
ORIGIN_GRID964  -2.4346301  0.0977674 -24.902  < 2e-16 ***
ORIGIN_GRID966   4.0992582  0.0353168 116.071  < 2e-16 ***
ORIGIN_GRID967  -1.6723961  0.0677108 -24.699  < 2e-16 ***
ORIGIN_GRID972   2.0580511  0.0353847  58.162  < 2e-16 ***
ORIGIN_GRID973   2.0247243  0.0353884  57.214  < 2e-16 ***
ORIGIN_GRID974   1.9297682  0.0353543  54.584  < 2e-16 ***
ORIGIN_GRID975   1.9409572  0.0353741  54.869  < 2e-16 ***
ORIGIN_GRID977   2.4736242  0.0353245  70.026  < 2e-16 ***
ORIGIN_GRID983  -0.7279712  0.0684189 -10.640  < 2e-16 ***
ORIGIN_GRID985   3.9268705  0.0353216 111.175  < 2e-16 ***
ORIGIN_GRID986   2.6072250  0.0354125  73.624  < 2e-16 ***
ORIGIN_GRID990  -0.0530288  0.0388706  -1.364 0.172493    
ORIGIN_GRID991   1.3302293  0.0368877  36.062  < 2e-16 ***
ORIGIN_GRID992   3.2823879  0.0356736  92.012  < 2e-16 ***
ORIGIN_GRID993   3.2906375  0.0353057  93.204  < 2e-16 ***
ORIGIN_GRID994   1.0241438  0.0358652  28.555  < 2e-16 ***
ORIGIN_GRID995   1.8467129  0.0353613  52.224  < 2e-16 ***
ORIGIN_GRID1001 -0.2412466  0.0399964  -6.032 1.62e-09 ***
ORIGIN_GRID1002 -0.9148496  0.0503973 -18.153  < 2e-16 ***
ORIGIN_GRID1003  2.8920866  0.0367404  78.717  < 2e-16 ***
ORIGIN_GRID1004  4.4703832  0.0353016 126.634  < 2e-16 ***
ORIGIN_GRID1005  1.3062462  0.0368414  35.456  < 2e-16 ***
ORIGIN_GRID1010  1.8664070  0.0353603  52.783  < 2e-16 ***
ORIGIN_GRID1011  0.8564393  0.0356567  24.019  < 2e-16 ***
ORIGIN_GRID1012  1.0258626  0.0356764  28.755  < 2e-16 ***
ORIGIN_GRID1013  1.7040519  0.0353888  48.152  < 2e-16 ***
ORIGIN_GRID1014  1.5321144  0.0356022  43.034  < 2e-16 ***
ORIGIN_GRID1023  4.7569924  0.0353128 134.710  < 2e-16 ***
ORIGIN_GRID1024  4.2461204  0.0353085 120.258  < 2e-16 ***
ORIGIN_GRID1025  2.5210802  0.0356212  70.775  < 2e-16 ***
ORIGIN_GRID1028  0.6450375  0.0355109  18.164  < 2e-16 ***
ORIGIN_GRID1030  0.7508730  0.0359374  20.894  < 2e-16 ***
ORIGIN_GRID1031  2.4897728  0.0353123  70.507  < 2e-16 ***
ORIGIN_GRID1033  1.9696546  0.0353345  55.743  < 2e-16 ***
ORIGIN_GRID1040 -0.0756048  0.0402350  -1.879 0.060233 .  
ORIGIN_GRID1041  2.4435840  0.0355666  68.705  < 2e-16 ***
ORIGIN_GRID1042  4.5661732  0.0353065 129.329  < 2e-16 ***
ORIGIN_GRID1043  3.3578560  0.0353299  95.043  < 2e-16 ***
ORIGIN_GRID1048  1.2874569  0.0354273  36.341  < 2e-16 ***
ORIGIN_GRID1049  2.1337542  0.0353253  60.403  < 2e-16 ***
ORIGIN_GRID1050  3.0942985  0.0353061  87.642  < 2e-16 ***
ORIGIN_GRID1061  5.0330528  0.0353103 142.538  < 2e-16 ***
ORIGIN_GRID1062  4.9187608  0.0353072 139.313  < 2e-16 ***
ORIGIN_GRID1063  2.0256247  0.0354633  57.119  < 2e-16 ***
ORIGIN_GRID1064 -0.2724448  0.0951295  -2.864 0.004184 ** 
ORIGIN_GRID1066  1.0243338  0.0353901  28.944  < 2e-16 ***
ORIGIN_GRID1067  1.9881457  0.0353324  56.270  < 2e-16 ***
ORIGIN_GRID1068  2.7414186  0.0353099  77.639  < 2e-16 ***
ORIGIN_GRID1069  1.9608230  0.0353318  55.497  < 2e-16 ***
ORIGIN_GRID1071  0.8096587  0.0354985  22.808  < 2e-16 ***
ORIGIN_GRID1078  0.2637753  0.0396491   6.653 2.88e-11 ***
ORIGIN_GRID1080  4.2614319  0.0353212 120.648  < 2e-16 ***
ORIGIN_GRID1081  3.7858220  0.0353174 107.194  < 2e-16 ***
ORIGIN_GRID1082  1.9297018  0.0355220  54.324  < 2e-16 ***
ORIGIN_GRID1086  2.9351013  0.0353290  83.079  < 2e-16 ***
ORIGIN_GRID1087  2.2075889  0.0353289  62.487  < 2e-16 ***
ORIGIN_GRID1089  2.3079329  0.0353291  65.327  < 2e-16 ***
ORIGIN_GRID1090  1.8454595  0.0353497  52.206  < 2e-16 ***
ORIGIN_GRID1097 -0.3107555  0.0488939  -6.356 2.07e-10 ***
ORIGIN_GRID1100  4.5549994  0.0353107 128.998  < 2e-16 ***
ORIGIN_GRID1101  1.9458997  0.0369126  52.716  < 2e-16 ***
ORIGIN_GRID1102  0.6182130  0.0373080  16.571  < 2e-16 ***
ORIGIN_GRID1104  2.8465351  0.0353095  80.617  < 2e-16 ***
ORIGIN_GRID1105  2.6644631  0.0353106  75.458  < 2e-16 ***
ORIGIN_GRID1106  2.9944035  0.0353788  84.638  < 2e-16 ***
ORIGIN_GRID1107  0.6912737  0.0357704  19.325  < 2e-16 ***
ORIGIN_GRID1108  1.1785841  0.0353799  33.312  < 2e-16 ***
ORIGIN_GRID1115 -1.8644059  0.0835857 -22.305  < 2e-16 ***
ORIGIN_GRID1116 -0.7137493  0.0548226 -13.019  < 2e-16 ***
ORIGIN_GRID1119  2.2399567  0.0354733  63.145  < 2e-16 ***
ORIGIN_GRID1120  2.1679634  0.0355255  61.026  < 2e-16 ***
ORIGIN_GRID1123  1.1671398  0.0354138  32.957  < 2e-16 ***
ORIGIN_GRID1124  2.8426530  0.0353301  80.460  < 2e-16 ***
ORIGIN_GRID1125  2.8628820  0.0353130  81.072  < 2e-16 ***
ORIGIN_GRID1128  1.1107689  0.0354116  31.367  < 2e-16 ***
ORIGIN_GRID1138  3.5377887  0.0353439 100.096  < 2e-16 ***
ORIGIN_GRID1139  4.8491361  0.0353163 137.306  < 2e-16 ***
ORIGIN_GRID1140  1.7927169  0.0355292  50.458  < 2e-16 ***
ORIGIN_GRID1142  2.3689598  0.0353775  66.962  < 2e-16 ***
ORIGIN_GRID1143  2.1268607  0.0353129  60.229  < 2e-16 ***
ORIGIN_GRID1144  1.8152274  0.0356062  50.981  < 2e-16 ***
ORIGIN_GRID1145  1.0066052  0.0356682  28.221  < 2e-16 ***
ORIGIN_GRID1146  1.9177926  0.0353533  54.246  < 2e-16 ***
ORIGIN_GRID1147 -0.1757162  0.0367449  -4.782 1.74e-06 ***
ORIGIN_GRID1152 -1.6293587  0.0569997 -28.585  < 2e-16 ***
ORIGIN_GRID1153  1.4780427  0.0354930  41.643  < 2e-16 ***
ORIGIN_GRID1157  3.7913631  0.0353086 107.378  < 2e-16 ***
ORIGIN_GRID1158  1.7040556  0.0354961  48.007  < 2e-16 ***
ORIGIN_GRID1161  2.8542377  0.0353089  80.836  < 2e-16 ***
ORIGIN_GRID1162  3.3212321  0.0353113  94.056  < 2e-16 ***
ORIGIN_GRID1163  3.5397537  0.0353059 100.260  < 2e-16 ***
ORIGIN_GRID1164  1.7016595  0.0354920  47.945  < 2e-16 ***
ORIGIN_GRID1167 -0.8058098  0.0394726 -20.414  < 2e-16 ***
ORIGIN_GRID1171 -1.3572517  0.0487773 -27.825  < 2e-16 ***
ORIGIN_GRID1172  3.0030417  0.0353398  84.976  < 2e-16 ***
ORIGIN_GRID1173  0.6720743  0.0362014  18.565  < 2e-16 ***
ORIGIN_GRID1176  2.8436024  0.0353365  80.472  < 2e-16 ***
ORIGIN_GRID1177  3.8154266  0.0353282 107.999  < 2e-16 ***
ORIGIN_GRID1180  3.8295816  0.0353078 108.463  < 2e-16 ***
ORIGIN_GRID1181  2.7559089  0.0353101  78.049  < 2e-16 ***
ORIGIN_GRID1183 -0.1055131  0.0371124  -2.843 0.004468 ** 
ORIGIN_GRID1184  2.0470523  0.0353451  57.916  < 2e-16 ***
ORIGIN_GRID1186 -1.6452285  0.0632352 -26.018  < 2e-16 ***
ORIGIN_GRID1192  0.0131711  0.0371079   0.355 0.722635    
ORIGIN_GRID1193  1.6119088  0.0355006  45.405  < 2e-16 ***
ORIGIN_GRID1194  1.1795073  0.0356251  33.109  < 2e-16 ***
ORIGIN_GRID1195  3.6654461  0.0353082 103.813  < 2e-16 ***
ORIGIN_GRID1196  2.6968399  0.0354470  76.081  < 2e-16 ***
ORIGIN_GRID1199  1.0919213  0.0355195  30.741  < 2e-16 ***
ORIGIN_GRID1200  2.9952374  0.0353102  84.827  < 2e-16 ***
ORIGIN_GRID1201  2.8892640  0.0353107  81.824  < 2e-16 ***
ORIGIN_GRID1202  1.4476143  0.0353893  40.905  < 2e-16 ***
ORIGIN_GRID1203  1.7133349  0.0355278  48.225  < 2e-16 ***
ORIGIN_GRID1204  2.3401055  0.0354077  66.090  < 2e-16 ***
ORIGIN_GRID1205 -1.9294833  0.1250940 -15.424  < 2e-16 ***
ORIGIN_GRID1207  1.1238936  0.0355209  31.640  < 2e-16 ***
ORIGIN_GRID1208  1.4121157  0.0354424  39.843  < 2e-16 ***
ORIGIN_GRID1209  0.8889926  0.0355400  25.014  < 2e-16 ***
ORIGIN_GRID1210 -1.7137737  0.0524425 -32.679  < 2e-16 ***
ORIGIN_GRID1211 -1.2244891  0.0396844 -30.856  < 2e-16 ***
ORIGIN_GRID1212 -1.1480395  0.0446143 -25.733  < 2e-16 ***
ORIGIN_GRID1213  3.7420129  0.0353070 105.985  < 2e-16 ***
ORIGIN_GRID1214  2.1367857  0.0353566  60.435  < 2e-16 ***
ORIGIN_GRID1215 -2.2183550  0.2631072  -8.431  < 2e-16 ***
ORIGIN_GRID1218  2.5402508  0.0353367  71.887  < 2e-16 ***
ORIGIN_GRID1219  3.8139489  0.0353053 108.028  < 2e-16 ***
ORIGIN_GRID1220  2.1018619  0.0353530  59.454  < 2e-16 ***
ORIGIN_GRID1221  1.6523594  0.0353456  46.749  < 2e-16 ***
ORIGIN_GRID1222  1.7170408  0.0354887  48.383  < 2e-16 ***
ORIGIN_GRID1225  1.4436055  0.0353595  40.827  < 2e-16 ***
ORIGIN_GRID1226  1.0952479  0.0354323  30.911  < 2e-16 ***
ORIGIN_GRID1227  1.8655214  0.0353985  52.701  < 2e-16 ***
ORIGIN_GRID1229  0.5464907  0.0359842  15.187  < 2e-16 ***
ORIGIN_GRID1230  1.9131776  0.0353359  54.143  < 2e-16 ***
ORIGIN_GRID1231  3.1283979  0.0353168  88.581  < 2e-16 ***
ORIGIN_GRID1232  3.4934295  0.0353212  98.905  < 2e-16 ***
ORIGIN_GRID1233  4.3197103  0.0353128 122.327  < 2e-16 ***
ORIGIN_GRID1234  0.3774647  0.0393720   9.587  < 2e-16 ***
ORIGIN_GRID1238  1.5327602  0.0353519  43.357  < 2e-16 ***
ORIGIN_GRID1239  1.6830967  0.0353412  47.624  < 2e-16 ***
ORIGIN_GRID1240  2.2889414  0.0353122  64.820  < 2e-16 ***
ORIGIN_GRID1241  1.6804998  0.0354404  47.418  < 2e-16 ***
ORIGIN_GRID1242  0.7603054  0.0356455  21.330  < 2e-16 ***
ORIGIN_GRID1243 -0.9676370  0.0384664 -25.155  < 2e-16 ***
ORIGIN_GRID1244  0.9436235  0.0354794  26.596  < 2e-16 ***
ORIGIN_GRID1245  2.9563580  0.0353348  83.667  < 2e-16 ***
ORIGIN_GRID1246  3.2662982  0.0354220  92.211  < 2e-16 ***
ORIGIN_GRID1249  0.6552800  0.0367526  17.829  < 2e-16 ***
ORIGIN_GRID1250  3.5997634  0.0353043 101.964  < 2e-16 ***
ORIGIN_GRID1251  3.8413568  0.0353068 108.799  < 2e-16 ***
ORIGIN_GRID1252  3.3709109  0.0353237  95.429  < 2e-16 ***
ORIGIN_GRID1253  1.2169211  0.0365178  33.324  < 2e-16 ***
ORIGIN_GRID1256  1.7223625  0.0353316  48.748  < 2e-16 ***
ORIGIN_GRID1257  1.3173351  0.0353620  37.253  < 2e-16 ***
ORIGIN_GRID1258  2.3036777  0.0353409  65.184  < 2e-16 ***
ORIGIN_GRID1259  1.9528230  0.0353527  55.238  < 2e-16 ***
ORIGIN_GRID1260  1.6361044  0.0357115  45.815  < 2e-16 ***
ORIGIN_GRID1261  0.7749147  0.0355720  21.784  < 2e-16 ***
ORIGIN_GRID1262  1.5442497  0.0353905  43.635  < 2e-16 ***
ORIGIN_GRID1263  1.9083882  0.0353342  54.010  < 2e-16 ***
ORIGIN_GRID1264  2.9152626  0.0353149  82.551  < 2e-16 ***
ORIGIN_GRID1265  3.1618980  0.0353173  89.528  < 2e-16 ***
ORIGIN_GRID1266  1.5826659  0.0354544  44.640  < 2e-16 ***
ORIGIN_GRID1268  3.9386602  0.0353264 111.493  < 2e-16 ***
ORIGIN_GRID1269  3.0431633  0.0353071  86.191  < 2e-16 ***
ORIGIN_GRID1270  3.8985389  0.0353103 110.408  < 2e-16 ***
ORIGIN_GRID1272  4.1561094  0.0357055 116.400  < 2e-16 ***
ORIGIN_GRID1276  1.4181119  0.0353255  40.144  < 2e-16 ***
ORIGIN_GRID1277  2.0727363  0.0353372  58.656  < 2e-16 ***
ORIGIN_GRID1278  1.7750067  0.0353220  50.252  < 2e-16 ***
ORIGIN_GRID1279  2.5513751  0.0353233  72.229  < 2e-16 ***
ORIGIN_GRID1280  1.9562025  0.0353426  55.350  < 2e-16 ***
ORIGIN_GRID1281  1.6589026  0.0353728  46.898  < 2e-16 ***
ORIGIN_GRID1282  2.1579086  0.0353278  61.083  < 2e-16 ***
ORIGIN_GRID1283  2.2356439  0.0353298  63.279  < 2e-16 ***
ORIGIN_GRID1284  3.0394706  0.0353132  86.072  < 2e-16 ***
ORIGIN_GRID1285  2.3721396  0.0353307  67.141  < 2e-16 ***
ORIGIN_GRID1288  4.2563367  0.0353152 120.524  < 2e-16 ***
ORIGIN_GRID1289  5.3783782  0.0353054 152.339  < 2e-16 ***
ORIGIN_GRID1294  2.1126482  0.0353164  59.821  < 2e-16 ***
ORIGIN_GRID1295  2.2309458  0.0353096  63.182  < 2e-16 ***
ORIGIN_GRID1296  2.4245622  0.0353161  68.653  < 2e-16 ***
ORIGIN_GRID1297  0.9263188  0.0355615  26.048  < 2e-16 ***
ORIGIN_GRID1298  2.5496957  0.0353199  72.189  < 2e-16 ***
ORIGIN_GRID1299  2.8218021  0.0353103  79.914  < 2e-16 ***
ORIGIN_GRID1300  0.1070987  0.0357279   2.998 0.002721 ** 
ORIGIN_GRID1301  3.1406759  0.0353098  88.946  < 2e-16 ***
ORIGIN_GRID1302  3.3165093  0.0353057  93.937  < 2e-16 ***
ORIGIN_GRID1303  3.8542117  0.0353034 109.174  < 2e-16 ***
ORIGIN_GRID1304  0.3813311  0.0359293  10.613  < 2e-16 ***
ORIGIN_GRID1306  3.3645484  0.0353333  95.223  < 2e-16 ***
ORIGIN_GRID1307  4.5812742  0.0353080 129.752  < 2e-16 ***
ORIGIN_GRID1308  4.4013782  0.0353353 124.560  < 2e-16 ***
ORIGIN_GRID1314  1.4758737  0.0353228  41.782  < 2e-16 ***
ORIGIN_GRID1315  1.5214066  0.0353318  43.061  < 2e-16 ***
ORIGIN_GRID1316  0.9364213  0.0355442  26.345  < 2e-16 ***
ORIGIN_GRID1317  2.2291154  0.0353416  63.073  < 2e-16 ***
ORIGIN_GRID1318  2.9640817  0.0353195  83.922  < 2e-16 ***
ORIGIN_GRID1319  3.0952486  0.0353076  87.665  < 2e-16 ***
ORIGIN_GRID1320  3.1194825  0.0353065  88.354  < 2e-16 ***
ORIGIN_GRID1321  3.2185331  0.0353129  91.143  < 2e-16 ***
ORIGIN_GRID1322  2.3385105  0.0353218  66.206  < 2e-16 ***
ORIGIN_GRID1323  1.2286022  0.0356487  34.464  < 2e-16 ***
ORIGIN_GRID1326  4.6084432  0.0353072 130.524  < 2e-16 ***
ORIGIN_GRID1327  4.4996921  0.0353170 127.409  < 2e-16 ***
ORIGIN_GRID1332  0.2140315  0.0356469   6.004 1.92e-09 ***
ORIGIN_GRID1333  1.1846029  0.0353458  33.515  < 2e-16 ***
ORIGIN_GRID1334  1.9490392  0.0353122  55.194  < 2e-16 ***
ORIGIN_GRID1335  2.8693782  0.0353068  81.270  < 2e-16 ***
ORIGIN_GRID1336  2.8304100  0.0353269  80.121  < 2e-16 ***
ORIGIN_GRID1337  3.5198098  0.0353024  99.705  < 2e-16 ***
ORIGIN_GRID1338  2.1269202  0.0353238  60.212  < 2e-16 ***
ORIGIN_GRID1339  2.4032771  0.0353272  68.029  < 2e-16 ***
ORIGIN_GRID1340  3.7144152  0.0353023 105.217  < 2e-16 ***
ORIGIN_GRID1341  1.9380575  0.0354045  54.740  < 2e-16 ***
ORIGIN_GRID1342  1.4317901  0.0354767  40.359  < 2e-16 ***
ORIGIN_GRID1345  4.0660606  0.0353142 115.139  < 2e-16 ***
ORIGIN_GRID1352  1.3929605  0.0353830  39.368  < 2e-16 ***
ORIGIN_GRID1353  1.7009521  0.0353340  48.139  < 2e-16 ***
ORIGIN_GRID1354  2.3414409  0.0353078  66.315  < 2e-16 ***
ORIGIN_GRID1355  3.1230212  0.0353122  88.440  < 2e-16 ***
ORIGIN_GRID1356  3.6046604  0.0353075 102.093  < 2e-16 ***
ORIGIN_GRID1357  3.1743939  0.0353065  89.910  < 2e-16 ***
ORIGIN_GRID1358  3.9789459  0.0353202 112.654  < 2e-16 ***
ORIGIN_GRID1359  3.4049874  0.0353064  96.441  < 2e-16 ***
ORIGIN_GRID1360  3.1943834  0.0353111  90.464  < 2e-16 ***
ORIGIN_GRID1364 -0.5481085  0.0552367  -9.923  < 2e-16 ***
ORIGIN_GRID1371  0.2540909  0.0360627   7.046 1.84e-12 ***
ORIGIN_GRID1372  1.8690059  0.0353176  52.920  < 2e-16 ***
ORIGIN_GRID1373  2.5415547  0.0353192  71.960  < 2e-16 ***
ORIGIN_GRID1374  2.8246355  0.0353339  79.941  < 2e-16 ***
ORIGIN_GRID1375  4.3939036  0.0353124 124.429  < 2e-16 ***
ORIGIN_GRID1376  2.1715638  0.0353325  61.461  < 2e-16 ***
ORIGIN_GRID1377  1.2490129  0.0354627  35.220  < 2e-16 ***
ORIGIN_GRID1378  3.6369744  0.0353055 103.014  < 2e-16 ***
ORIGIN_GRID1379  1.5989204  0.0357456  44.731  < 2e-16 ***
ORIGIN_GRID1380  2.0859360  0.0354158  58.898  < 2e-16 ***
ORIGIN_GRID1383  1.9455729  0.0357915  54.358  < 2e-16 ***
ORIGIN_GRID1389  0.9085215  0.0462896  19.627  < 2e-16 ***
ORIGIN_GRID1390 -0.2532037  0.0361025  -7.013 2.32e-12 ***
ORIGIN_GRID1391  0.6313959  0.0354701  17.801  < 2e-16 ***
ORIGIN_GRID1392  1.8309964  0.0353157  51.846  < 2e-16 ***
ORIGIN_GRID1393  2.5063814  0.0353108  70.981  < 2e-16 ***
ORIGIN_GRID1394  3.2997603  0.0353106  93.450  < 2e-16 ***
ORIGIN_GRID1395  5.9511737  0.0353136 168.524  < 2e-16 ***
ORIGIN_GRID1396  1.8734957  0.0356482  52.555  < 2e-16 ***
ORIGIN_GRID1397  3.3728222  0.0356038  94.732  < 2e-16 ***
ORIGIN_GRID1398  3.4929027  0.0353243  98.881  < 2e-16 ***
ORIGIN_GRID1401 -0.5581273  0.0409465 -13.631  < 2e-16 ***
ORIGIN_GRID1408  1.5219253  0.0403510  37.717  < 2e-16 ***
ORIGIN_GRID1409 -0.2651373  0.0370520  -7.156 8.32e-13 ***
ORIGIN_GRID1410  1.3679720  0.0358288  38.181  < 2e-16 ***
ORIGIN_GRID1411  2.3360116  0.0353090  66.159  < 2e-16 ***
ORIGIN_GRID1412  3.5270933  0.0353046  99.905  < 2e-16 ***
ORIGIN_GRID1413  3.2297832  0.0353127  91.462  < 2e-16 ***
ORIGIN_GRID1414  0.5020073  0.0358767  13.993  < 2e-16 ***
ORIGIN_GRID1415  1.9741947  0.0353472  55.851  < 2e-16 ***
ORIGIN_GRID1416  1.2681769  0.0354715  35.752  < 2e-16 ***
ORIGIN_GRID1417  1.4714495  0.0355391  41.404  < 2e-16 ***
ORIGIN_GRID1418  0.6509674  0.0357944  18.186  < 2e-16 ***
ORIGIN_GRID1419 -0.8698596  0.0464212 -18.738  < 2e-16 ***
ORIGIN_GRID1420 -0.4142901  0.0426470  -9.714  < 2e-16 ***
ORIGIN_GRID1428 -2.2183550  0.2248856  -9.864  < 2e-16 ***
ORIGIN_GRID1430  2.1094450  0.0354209  59.554  < 2e-16 ***
ORIGIN_GRID1431  0.2542646  0.0355601   7.150 8.66e-13 ***
ORIGIN_GRID1432  3.0281476  0.0353081  85.763  < 2e-16 ***
ORIGIN_GRID1433  3.5730455  0.0356867 100.123  < 2e-16 ***
ORIGIN_GRID1434  1.9745047  0.0353706  55.823  < 2e-16 ***
ORIGIN_GRID1435  3.0263880  0.0353781  85.544  < 2e-16 ***
ORIGIN_GRID1436  1.2626630  0.0354155  35.653  < 2e-16 ***
ORIGIN_GRID1439 -1.3962495  0.0527287 -26.480  < 2e-16 ***
ORIGIN_GRID1440 -0.5677866  0.0403956 -14.056  < 2e-16 ***
ORIGIN_GRID1448  3.6162630  0.0354353 102.053  < 2e-16 ***
ORIGIN_GRID1449  1.5015143  0.0353429  42.484  < 2e-16 ***
ORIGIN_GRID1450  2.9353337  0.0353179  83.112  < 2e-16 ***
ORIGIN_GRID1451  3.5627749  0.0353071 100.908  < 2e-16 ***
ORIGIN_GRID1452  1.8907450  0.0353549  53.479  < 2e-16 ***
ORIGIN_GRID1453  3.0136230  0.0353082  85.352  < 2e-16 ***
ORIGIN_GRID1454  4.5509977  0.0353595 128.707  < 2e-16 ***
ORIGIN_GRID1455  2.1145581  0.0354000  59.733  < 2e-16 ***
ORIGIN_GRID1456  3.4229154  0.0353104  96.938  < 2e-16 ***
ORIGIN_GRID1457  3.0084354  0.0353499  85.104  < 2e-16 ***
ORIGIN_GRID1458  0.0239519  0.0422007   0.568 0.570325    
ORIGIN_GRID1468  3.1521334  0.0356476  88.425  < 2e-16 ***
ORIGIN_GRID1469  2.7659976  0.0353070  78.341  < 2e-16 ***
ORIGIN_GRID1470  2.0189422  0.0353457  57.120  < 2e-16 ***
ORIGIN_GRID1471  3.2276582  0.0353152  91.396  < 2e-16 ***
ORIGIN_GRID1472  3.4171251  0.0353039  96.792  < 2e-16 ***
ORIGIN_GRID1473  2.1081657  0.0353358  59.661  < 2e-16 ***
ORIGIN_GRID1474  3.5565944  0.0353051 100.739  < 2e-16 ***
ORIGIN_GRID1475  2.7455672  0.0353355  77.700  < 2e-16 ***
ORIGIN_GRID1476  2.9017155  0.0353439  82.100  < 2e-16 ***
ORIGIN_GRID1477 -0.6692029  0.0422270 -15.848  < 2e-16 ***
ORIGIN_GRID1486  1.5035548  0.0370140  40.621  < 2e-16 ***
ORIGIN_GRID1487  2.6809363  0.0353172  75.910  < 2e-16 ***
ORIGIN_GRID1488  1.6927562  0.0354680  47.726  < 2e-16 ***
ORIGIN_GRID1489  2.4789642  0.0353178  70.190  < 2e-16 ***
ORIGIN_GRID1490  2.4013792  0.0353993  67.837  < 2e-16 ***
ORIGIN_GRID1491  2.3535129  0.0353171  66.639  < 2e-16 ***
ORIGIN_GRID1492  2.7072194  0.0353150  76.659  < 2e-16 ***
ORIGIN_GRID1493  3.5153120  0.0353062  99.566  < 2e-16 ***
ORIGIN_GRID1494  3.7342427  0.0353130 105.747  < 2e-16 ***
ORIGIN_GRID1506 -0.6979177  0.0538756 -12.954  < 2e-16 ***
ORIGIN_GRID1507  2.9996091  0.0353058  84.961  < 2e-16 ***
ORIGIN_GRID1508  2.0587818  0.0353254  58.281  < 2e-16 ***
ORIGIN_GRID1509  3.6959573  0.0353725 104.487  < 2e-16 ***
ORIGIN_GRID1510  3.0452694  0.0353132  86.236  < 2e-16 ***
ORIGIN_GRID1512  3.5865849  0.0353049 101.589  < 2e-16 ***
ORIGIN_GRID1513  5.3568525  0.0353169 151.680  < 2e-16 ***
ORIGIN_GRID1514  4.2351309  0.0353252 119.890  < 2e-16 ***
ORIGIN_GRID1524  2.1097687  0.0354400  59.531  < 2e-16 ***
ORIGIN_GRID1525  2.6375412  0.0353134  74.689  < 2e-16 ***
ORIGIN_GRID1526  2.9877661  0.0353156  84.602  < 2e-16 ***
ORIGIN_GRID1527  2.8170215  0.0353289  79.737  < 2e-16 ***
ORIGIN_GRID1528  1.7903535  0.0353597  50.633  < 2e-16 ***
ORIGIN_GRID1529  1.5874129  0.0353953  44.848  < 2e-16 ***
ORIGIN_GRID1530  2.9273632  0.0353267  82.865  < 2e-16 ***
ORIGIN_GRID1531  3.3908824  0.0353110  96.029  < 2e-16 ***
ORIGIN_GRID1532  2.9500691  0.0353481  83.458  < 2e-16 ***
ORIGIN_GRID1544  2.6007430  0.0353260  73.621  < 2e-16 ***
ORIGIN_GRID1545  2.4488801  0.0353127  69.348  < 2e-16 ***
ORIGIN_GRID1546  3.2163392  0.0353075  91.095  < 2e-16 ***
ORIGIN_GRID1547  2.0913591  0.0353320  59.192  < 2e-16 ***
ORIGIN_GRID1548  3.3060971  0.0353093  93.633  < 2e-16 ***
ORIGIN_GRID1549  3.2503298  0.0353107  92.050  < 2e-16 ***
ORIGIN_GRID1550  3.6702785  0.0353045 103.961  < 2e-16 ***
ORIGIN_GRID1551  1.6986653  0.0354763  47.882  < 2e-16 ***
ORIGIN_GRID1552  4.1004760  0.0353125 116.120  < 2e-16 ***
ORIGIN_GRID1563  2.7592391  0.0353225  78.116  < 2e-16 ***
ORIGIN_GRID1564  2.7404967  0.0353097  77.613  < 2e-16 ***
ORIGIN_GRID1565  2.3948314  0.0353153  67.813  < 2e-16 ***
ORIGIN_GRID1566  0.4009290  0.0357474  11.216  < 2e-16 ***
ORIGIN_GRID1567  2.7375205  0.0353145  77.518  < 2e-16 ***
ORIGIN_GRID1568  3.3505159  0.0353071  94.896  < 2e-16 ***
ORIGIN_GRID1569  3.1213077  0.0353113  88.394  < 2e-16 ***
ORIGIN_GRID1570  3.4377845  0.0353107  97.358  < 2e-16 ***
ORIGIN_GRID1571  5.7571450  0.0353284 162.961  < 2e-16 ***
ORIGIN_GRID1582  1.5239186  0.0354126  43.033  < 2e-16 ***
ORIGIN_GRID1583  2.2054256  0.0353119  62.456  < 2e-16 ***
ORIGIN_GRID1584  1.8502731  0.0353362  52.362  < 2e-16 ***
ORIGIN_GRID1585  1.4959522  0.0353964  42.263  < 2e-16 ***
ORIGIN_GRID1587  3.3832673  0.0353072  95.824  < 2e-16 ***
ORIGIN_GRID1588  3.3687890  0.0353042  95.422  < 2e-16 ***
ORIGIN_GRID1589  3.1322589  0.0353102  88.707  < 2e-16 ***
ORIGIN_GRID1590  3.3775910  0.0353217  95.624  < 2e-16 ***
ORIGIN_GRID1591  2.7465258  0.0359434  76.413  < 2e-16 ***
ORIGIN_GRID1601  2.4588042  0.0353220  69.611  < 2e-16 ***
ORIGIN_GRID1602  2.0625497  0.0353537  58.340  < 2e-16 ***
ORIGIN_GRID1603  1.8460734  0.0353857  52.170  < 2e-16 ***
ORIGIN_GRID1604  1.9882759  0.0364261  54.584  < 2e-16 ***
ORIGIN_GRID1606  2.9735402  0.0353107  84.211  < 2e-16 ***
ORIGIN_GRID1607  2.9611573  0.0353210  83.836  < 2e-16 ***
ORIGIN_GRID1608  3.6057707  0.0353044 102.134  < 2e-16 ***
ORIGIN_GRID1609  3.6908853  0.0353100 104.528  < 2e-16 ***
ORIGIN_GRID1610  4.4134468  0.0353940 124.695  < 2e-16 ***
ORIGIN_GRID1620  2.7873205  0.0353166  78.924  < 2e-16 ***
ORIGIN_GRID1621  2.0858998  0.0353218  59.054  < 2e-16 ***
ORIGIN_GRID1622  3.4310326  0.0353241  97.130  < 2e-16 ***
ORIGIN_GRID1623  1.0037186  0.0354559  28.309  < 2e-16 ***
ORIGIN_GRID1624  1.6252289  0.0368513  44.102  < 2e-16 ***
ORIGIN_GRID1625  0.2377741  0.0364025   6.532 6.50e-11 ***
ORIGIN_GRID1626  3.5486859  0.0353112 100.497  < 2e-16 ***
ORIGIN_GRID1627  3.4979571  0.0353069  99.073  < 2e-16 ***
ORIGIN_GRID1628  3.7428281  0.0353085 106.004  < 2e-16 ***
ORIGIN_GRID1629  2.6139609  0.0353329  73.981  < 2e-16 ***
ORIGIN_GRID1630  2.9728055  0.0360346  82.499  < 2e-16 ***
ORIGIN_GRID1639  2.2826578  0.0353388  64.594  < 2e-16 ***
ORIGIN_GRID1640  2.9651438  0.0353055  83.985  < 2e-16 ***
ORIGIN_GRID1641  3.0635447  0.0353058  86.772  < 2e-16 ***
ORIGIN_GRID1645  3.7844852  0.0353237 107.137  < 2e-16 ***
ORIGIN_GRID1646  3.6959091  0.0353097 104.671  < 2e-16 ***
ORIGIN_GRID1647  3.4857779  0.0353065  98.729  < 2e-16 ***
ORIGIN_GRID1648  2.5507892  0.0363375  70.197  < 2e-16 ***
ORIGIN_GRID1658  2.6223137  0.0353116  74.262  < 2e-16 ***
ORIGIN_GRID1659  2.2574168  0.0353398  63.877  < 2e-16 ***
ORIGIN_GRID1660  2.7409544  0.0353161  77.612  < 2e-16 ***
ORIGIN_GRID1661  2.3152943  0.0353326  65.529  < 2e-16 ***
ORIGIN_GRID1663  0.2519943  0.0420889   5.987 2.13e-09 ***
ORIGIN_GRID1665  3.0575984  0.0353379  86.525  < 2e-16 ***
ORIGIN_GRID1666  4.3950722  0.0353028 124.496  < 2e-16 ***
ORIGIN_GRID1667  1.8882596  0.0363377  51.964  < 2e-16 ***
ORIGIN_GRID1668  4.8931488  0.0353995 138.227  < 2e-16 ***
ORIGIN_GRID1677  2.4865913  0.0353221  70.398  < 2e-16 ***
ORIGIN_GRID1678  2.7644019  0.0353121  78.285  < 2e-16 ***
ORIGIN_GRID1679  3.4016619  0.0353091  96.340  < 2e-16 ***
ORIGIN_GRID1682  1.5190935  0.0364029  41.730  < 2e-16 ***
ORIGIN_GRID1684  5.6761769  0.0353598 160.526  < 2e-16 ***
ORIGIN_GRID1685  3.6795296  0.0353117 104.201  < 2e-16 ***
ORIGIN_GRID1696  3.0120867  0.0353203  85.279  < 2e-16 ***
ORIGIN_GRID1697  2.2985171  0.0355494  64.657  < 2e-16 ***
ORIGIN_GRID1698  5.0082127  0.0353818 141.548  < 2e-16 ***
ORIGIN_GRID1699  3.0117795  0.0353127  85.289  < 2e-16 ***
ORIGIN_GRID1702  0.2967786  0.0402283   7.377 1.61e-13 ***
ORIGIN_GRID1704  3.4322843  0.0353120  97.199  < 2e-16 ***
ORIGIN_GRID1705  5.2915754  0.0353735 149.591  < 2e-16 ***
ORIGIN_GRID1715  2.6818371  0.0353142  75.942  < 2e-16 ***
ORIGIN_GRID1716  1.1809959  0.0354300  33.333  < 2e-16 ***
ORIGIN_GRID1717  2.9811299  0.0353418  84.351  < 2e-16 ***
ORIGIN_GRID1718 -1.1826608  0.0633014 -18.683  < 2e-16 ***
ORIGIN_GRID1721  0.0623569  0.0416505   1.497 0.134355    
ORIGIN_GRID1723  3.2218944  0.0353649  91.104  < 2e-16 ***
ORIGIN_GRID1735  1.8468343  0.0353710  52.213  < 2e-16 ***
ORIGIN_GRID1736  4.3542549  0.0353214 123.275  < 2e-16 ***
ORIGIN_GRID1737  3.0197711  0.0353154  85.509  < 2e-16 ***
ORIGIN_GRID1740  1.3191657  0.0367683  35.878  < 2e-16 ***
ORIGIN_GRID1742  3.0361781  0.0354582  85.627  < 2e-16 ***
ORIGIN_GRID1753  2.1444850  0.0353547  60.656  < 2e-16 ***
ORIGIN_GRID1754  2.7968816  0.0353113  79.206  < 2e-16 ***
ORIGIN_GRID1755  4.3408759  0.0353083 122.942  < 2e-16 ***
ORIGIN_GRID1758  0.2396022  0.0393189   6.094 1.10e-09 ***
ORIGIN_GRID1773  1.9680984  0.0353738  55.637  < 2e-16 ***
ORIGIN_GRID1774  3.5651198  0.0353026 100.987  < 2e-16 ***
ORIGIN_GRID1775  2.7460293  0.0353382  77.707  < 2e-16 ***
ORIGIN_GRID1776  3.5702723  0.0353143 101.100  < 2e-16 ***
ORIGIN_GRID1778 -0.0007325  0.0456058  -0.016 0.987186    
ORIGIN_GRID1791  1.9007126  0.0354067  53.682  < 2e-16 ***
ORIGIN_GRID1792  1.2305097  0.0354346  34.726  < 2e-16 ***
ORIGIN_GRID1793  3.7316120  0.0353097 105.682  < 2e-16 ***
ORIGIN_GRID1794  2.0967654  0.0355073  59.052  < 2e-16 ***
ORIGIN_GRID1795  4.0145781  0.0353120 113.689  < 2e-16 ***
ORIGIN_GRID1796  2.5984489  0.0353896  73.424  < 2e-16 ***
ORIGIN_GRID1797  2.7452160  0.0353325  77.697  < 2e-16 ***
ORIGIN_GRID1811  2.3029847  0.0353396  65.167  < 2e-16 ***
ORIGIN_GRID1812  3.1844070  0.0353061  90.194  < 2e-16 ***
ORIGIN_GRID1813  2.9416522  0.0353187  83.289  < 2e-16 ***
ORIGIN_GRID1814  4.4480579  0.0353083 125.978  < 2e-16 ***
ORIGIN_GRID1815  3.8145339  0.0353111 108.027  < 2e-16 ***
ORIGIN_GRID1816  2.5054307  0.0353550  70.865  < 2e-16 ***
ORIGIN_GRID1817  1.5153259  0.0355185  42.663  < 2e-16 ***
ORIGIN_GRID1830  3.6094421  0.0353198 102.193  < 2e-16 ***
ORIGIN_GRID1831  3.6408277  0.0353063 103.121  < 2e-16 ***
ORIGIN_GRID1832  2.9337027  0.0353134  83.076  < 2e-16 ***
ORIGIN_GRID1833  3.4981036  0.0353104  99.067  < 2e-16 ***
ORIGIN_GRID1834  2.9158845  0.0354182  82.327  < 2e-16 ***
ORIGIN_GRID1835  3.5750774  0.0353080 101.254  < 2e-16 ***
ORIGIN_GRID1849  2.0156373  0.0353781  56.974  < 2e-16 ***
ORIGIN_GRID1850  3.2232838  0.0353081  91.290  < 2e-16 ***
ORIGIN_GRID1851 -0.1328977  0.0391546  -3.394 0.000688 ***
ORIGIN_GRID1852  3.3138425  0.0353069  93.858  < 2e-16 ***
ORIGIN_GRID1853  3.6705592  0.0353218 103.918  < 2e-16 ***
ORIGIN_GRID1854  3.4085924  0.0353149  96.520  < 2e-16 ***
ORIGIN_GRID1855  3.5018666  0.0356306  98.283  < 2e-16 ***
ORIGIN_GRID1868  3.3685928  0.0353144  95.389  < 2e-16 ***
ORIGIN_GRID1869  2.0335813  0.0353514  57.525  < 2e-16 ***
ORIGIN_GRID1870  4.1874524  0.0355666 117.736  < 2e-16 ***
ORIGIN_GRID1871  4.0003289  0.0353016 113.319  < 2e-16 ***
ORIGIN_GRID1872  3.8440671  0.0353472 108.752  < 2e-16 ***
ORIGIN_GRID1873  3.2979201  0.0353200  93.373  < 2e-16 ***
ORIGIN_GRID1887  1.5706285  0.0353886  44.382  < 2e-16 ***
ORIGIN_GRID1888  3.3241744  0.0353181  94.121  < 2e-16 ***
ORIGIN_GRID1889  2.4237872  0.0353457  68.574  < 2e-16 ***
ORIGIN_GRID1890  3.3161042  0.0353114  93.910  < 2e-16 ***
ORIGIN_GRID1891  3.4342260  0.0353351  97.190  < 2e-16 ***
ORIGIN_GRID1892  3.5295369  0.0353049  99.973  < 2e-16 ***
ORIGIN_GRID1893  1.3725786  0.0432386  31.744  < 2e-16 ***
ORIGIN_GRID1905 -1.0370188  0.0514908 -20.140  < 2e-16 ***
ORIGIN_GRID1906  0.2838396  0.0358034   7.928 2.23e-15 ***
ORIGIN_GRID1907  1.5569438  0.0353753  44.012  < 2e-16 ***
ORIGIN_GRID1908  3.5184029  0.0353154  99.628  < 2e-16 ***
ORIGIN_GRID1909  3.5990928  0.0353097 101.929  < 2e-16 ***
ORIGIN_GRID1910  2.6811198  0.0353422  75.862  < 2e-16 ***
ORIGIN_GRID1911  2.4548158  0.0381111  64.412  < 2e-16 ***
ORIGIN_GRID1926  1.4883212  0.0355923  41.816  < 2e-16 ***
ORIGIN_GRID1927  1.3354521  0.0356877  37.420  < 2e-16 ***
ORIGIN_GRID1928  3.4557056  0.0353073  97.875  < 2e-16 ***
ORIGIN_GRID1929  4.2693862  0.0353104 120.910  < 2e-16 ***
ORIGIN_GRID1930  2.8354117  0.0353227  80.272  < 2e-16 ***
ORIGIN_GRID1944  1.8862874  0.0354724  53.176  < 2e-16 ***
ORIGIN_GRID1945  1.3157841  0.0357209  36.835  < 2e-16 ***
ORIGIN_GRID1946  3.6304515  0.0353112 102.813  < 2e-16 ***
ORIGIN_GRID1947  3.6468101  0.0353049 103.295  < 2e-16 ***
ORIGIN_GRID1948  3.6397431  0.0353063 103.090  < 2e-16 ***
ORIGIN_GRID1949  3.3605796  0.0353305  95.119  < 2e-16 ***
ORIGIN_GRID1965  2.4310150  0.0353583  68.754  < 2e-16 ***
ORIGIN_GRID1966  3.2513458  0.0353502  91.975  < 2e-16 ***
ORIGIN_GRID1967  2.6985523  0.0353182  76.407  < 2e-16 ***
ORIGIN_GRID1968  3.5509337  0.0353171 100.544  < 2e-16 ***
ORIGIN_GRID1983  2.4713635  0.0353754  69.861  < 2e-16 ***
ORIGIN_GRID1984  1.4964665  0.0354798  42.178  < 2e-16 ***
ORIGIN_GRID1985  3.0020263  0.0353266  84.979  < 2e-16 ***
ORIGIN_GRID1986  2.8027428  0.0353152  79.364  < 2e-16 ***
ORIGIN_GRID1987  3.8828431  0.0359332 108.057  < 2e-16 ***
ORIGIN_GRID2002 -0.1689061  0.0425704  -3.968 7.26e-05 ***
ORIGIN_GRID2003  0.1465948  0.0370049   3.961 7.45e-05 ***
ORIGIN_GRID2004  2.3743431  0.0359484  66.049  < 2e-16 ***
ORIGIN_GRID2005  2.9461177  0.0353539  83.332  < 2e-16 ***
ORIGIN_GRID2006  2.0299848  0.0354064  57.334  < 2e-16 ***
ORIGIN_GRID2021  1.3621018  0.0370402  36.774  < 2e-16 ***
ORIGIN_GRID2022  3.2574708  0.0358221  90.935  < 2e-16 ***
ORIGIN_GRID2023  1.9922250  0.0355423  56.052  < 2e-16 ***
ORIGIN_GRID2024  1.6781899  0.0356278  47.103  < 2e-16 ***
ORIGIN_GRID2025  0.7682070  0.0385287  19.939  < 2e-16 ***
ORIGIN_GRID2042  1.0611343  0.0390899  27.146  < 2e-16 ***
ORIGIN_GRID2043  1.6174867  0.0358131  45.165  < 2e-16 ***
ORIGIN_GRID2044  0.6611707  0.0356479  18.547  < 2e-16 ***
ORIGIN_GRID2045  1.5014742  0.0366456  40.973  < 2e-16 ***
ORIGIN_GRID2061  2.0182205  0.0383305  52.653  < 2e-16 ***
ORIGIN_GRID2062  1.7332677  0.0356443  48.627  < 2e-16 ***
ORIGIN_GRID2063  1.0513212  0.0357151  29.436  < 2e-16 ***
ORIGIN_GRID2064 -0.3084530  0.0458303  -6.730 1.69e-11 ***
ORIGIN_GRID2079  1.9602934  0.0354332  55.324  < 2e-16 ***
ORIGIN_GRID2082 -0.4828288  0.0405638 -11.903  < 2e-16 ***
ORIGIN_GRID2083  0.5988930  0.0359739  16.648  < 2e-16 ***
ORIGIN_GRID2098  0.6751204  0.0358492  18.832  < 2e-16 ***
ORIGIN_GRID2099  1.7263643  0.0353988  48.769  < 2e-16 ***
ORIGIN_GRID2102  1.4713371  0.0354153  41.545  < 2e-16 ***
ORIGIN_GRID2115  3.1067758  0.0356047  87.257  < 2e-16 ***
ORIGIN_GRID2119  1.8925631  0.0353824  53.489  < 2e-16 ***
ORIGIN_GRID2121  1.1285031  0.0354878  31.800  < 2e-16 ***
ORIGIN_GRID2137  1.5745608  0.0354152  44.460  < 2e-16 ***
ORIGIN_GRID2140 -0.9236562  0.0419432 -22.022  < 2e-16 ***
ORIGIN_GRID2153  2.8818206  0.0358346  80.420  < 2e-16 ***
ORIGIN_GRID2158  1.8919408  0.0356880  53.013  < 2e-16 ***
ORIGIN_GRID2177  1.7631415  0.0356334  49.480  < 2e-16 ***
ORIGIN_GRID2178  0.2222268  0.0373438   5.951 2.67e-09 ***
ORIGIN_GRID2196  2.0998802  0.0361849  58.032  < 2e-16 ***
ORIGIN_GRID2197  2.4178253  0.0354699  68.166  < 2e-16 ***
ORIGIN_GRID2267  1.5543954  0.0374052  41.556  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 1865411784  on 64935  degrees of freedom
Residual deviance: 1515309255  on 64122  degrees of freedom
AIC: 1522082949

Number of Fisher Scoring iterations: 8
  • For origin-constrained model, only explanatory variables representing the attractiveness at the destinations will be used.

  • All the explanatory variables including distance will be log transformed.

  • ORIGIN_SZ is used to model 𝜇𝑖 . It must be in categorical data type.

  • It is important to note that -1 is added in the equation after the distance variable. The -1 serves the purpose of removing the intercept that by default, glm will insert into the model.

and calculating R-Squared to determine the proportion of variance in the dependent variable that can be explained by the independent variables. In other words, R-Squared shows how well the data fit the regression model (the goodness of fit).

To obtain R-Squared value, we will be using the following helper function:

rsq <- function(observed,estimated){
  r <- cor(observed,estimated)
  R2 <- r^2
  R2
}
rsq(uncSIM$data$TRIPS, uncSIM$fitted.values)
[1] 0.2753955
r2_mcfadden(uncSIM)
# R2 for Generalized Linear Regression
       R2: 0.528
  adj. R2: 0.528

10 Model Comparison

11 Visual Fitting

12 Conclusion & Future Work

Reference

epsg.io (2023). EPSG: 3414 SVY21 / Singapore TM. https://epsg.io/3414

Kam, T. S. (2023). Processing and Visualising Flow Data. R for Geospatial Data Science and Analytics. https://r4gdsa.netlify.app/chap15

Kam, T. S. (2023). Calibrating Spatial Interaction Models with R. R for Geospatial Data Science and Analytics. https://r4gdsa.netlify.app/chap16

Miller, E. J. (2021). Traffic Analysis Zone Definition: Issues & Guidance. Travel Modelling Group. https://tmg.utoronto.ca/files/Reports/Traffic-Zone-Guidance_March-2021_Final.pdf